List denormalization with morphia - java

Suppose i have two morphia entities: Person and Team which are look like this
#Entity
public class Person {
private String name;
private String login;
private String mail;
private List<Team> teams;
}
#Entity
public class Team {
private String name;
private String description;
private List<Person> members;
//some more fields
}
I want map this model into Mongodb database like this
Users collection
{
name:"someName",
login:"somelogin",
mail:"some#mail.com",
teams: [
{id:"teamId", name:"TeamName"} //only specific fields fron Team Entity
{id:"anotherTeamId", name:"AnotherTeamName"}
]
}
Teams collection
{
id:"teamId",
name:"TeamName",
description:"Very strong team",
members: [id:"aaa", name: "someName"] //only specific fields fron User Entity
//some other fields
}
{
id:"anotherTeamId",
name:"AnotherTeamName",
description:"Brave new team",
members: [id:"aaa", name: "someName"] //only specific fields fron User Entity
//some other fields
}
So, I want denormolize only specific fields (only name for example) from Team document into User's teams field.
I don't understand Can I use morphia (or some other odm) for this case? Which annotations I should use in my Entities?
It seems that #Reference annotation is not allowed with List<> fields.
I think, i should create inner class PersonTeam, which will contain Team's name and id, and use it in Person class
#Entity
public class Person {
private String name;
private String login;
private String mail;
private List<PersonTeam> teams;
}
public class PersonTeam {
private String teamId;
private String teamName;
}
Is this a good way to solve my problem? thank you!

That's about the only way to do it with morphia at least. You might consider using #Reference on those fields and only storing the IDs. That'd help if your concern is saving space.

Related

Best practice for DTO classes that contain complex objects

If I have a Entity class as such where a user can have multiple addresses:
#Entity
public class User {
private String name;
private List<Address> address;
}
#Entity
public class Address {
private String area;
private String city;
}
Should the DTO exposed for the webservice contain Address object (like what User contains) or an AddressDTO object like this?
public class UserDTO {
private String name;
private List<AddressDTO> addressList;
}
Where can I find example code using DTO objects that contain nested objects as such, where I can see best practices on how to populate those nested objects inside the main DTO? (I've googled ad nauseam but so far no examples with this scenario)

How to add where on custom type in hibernate

EmployeeRepository class
CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
Root<Employee> employee = query.from(Employee.class);
query.select(employee)
.where(employee.get("address.city").in("pune","Mumbai","Delhi"));// getting error here
Employee class
class Employee {
private Long empId;
#Type(employeeCustomType)
private Address address; //this is custom type
// setter and getter
}
Address class
class Address{
private String city;
private Integer zipCode;
}
please just assume we have employeeCustomType class
any one have any idea on it.
I am just trying to add where clause on address object of city parameter.
using CriteriaBuilder.
Any other suggestion to achieve this scenario in hibernate

Spring Data Mongodb Using Object Type to Collection

Newbie Alert !
I just installed mongodb 2 days back and started creating REST api's over spring.
So i have a collection, userinfo, where a sample document would look like
{"_id":"5c62588e5e1fbc37dc9746d3","name":{"first":"rajan","last":"rawat"},"age":32}
I created the field name as Object type in the collection.
Now creating the entity class for it in java
#Document(collection = "userinfo")
public class UserInfo {
#Id
private String id;
private Name name;
private int age;
}
where the Class Name is
public class Name {
private String firstName;
private String lastName;
}
On running the API, the response I get is
{"id":"5c62588e5e1fbc37dc9746d3","name":{"firstName":null,"lastName":null},"age":32}
If I change the type in UserInfo class to string like,
#Document(collection = "userinfo")
public class UserInfo {
#Id
private String id;
private String name;
private int age;
}
The response changes to
{"id":"5c62588e5e1fbc37dc9746d3","name":"{ \"first\" : \"rajan\",
\"last\" : \"rawat\" }","age":32}
which basically gives a string representation of the object from collection.
My Questions.
Is there something wrong with the way I designed the collection in mongoDB. I am assuming my use case is a reason why the Object type would have been introduced.
How do I map this collection in java i.e #Document. What am I missing ? Is there Something else I need to configure in the Class Name
In your document your attributes name are "first" and "last", so in your class Name you need to use the same names so that the object can be mapped by spring.
just try this:
public class Name {
private String first;
private String last;
}

Spring-Data-Mongodb - How to look for a document, based on a field value of a document referenced within?

Here are my two classes :
#Document(collection="people")
public class Person {
// Data.
#Id
private ObjectId Id;
#Field("email")
private String email;
#DBRef
private List<Entity> entities;
/* Getters and setters removed to keep this question simple. */
}
And, here is my entity class.
#Document(collection = "entities")
public class Entity {
#Id
private ObjectId Id;
#DBRef
private List<Person> people;
/* Getters and setters removed to keep question simple. */
}
And here is my mongoRepository :
public interface EntityRepository extends MongoRepository<Entity, String>{
List<Entity> findByPeople_email(String email);
}
I think you can see what I want to do here - I want to query the mongo database, and get back all entities attached to a user where the email address matches the one I provide. I keep getting stuck in an SQL mindset here, and thinking I can just do something like :
SELECT * FROM people WHERE email="<email_here>"
But obviously that is not the case! Anyone know what I am missing?

Assigning a flat JSON object into multiple classes

I'm trying to figure out a way to assign select properties of the "participants" objects into specific classes:
This is the format that I'm working with
"participants": [
{
"person_id": "18044029",
"role_id": "35351535",
"person_name": "Lella Vignelli",
"person_date": "Italian, b. 1934",
"role_name": "Donor",
"role_display_name": "Donated by"
},
{
"person_id": "18042329",
"role_id": "35351535",
"person_name": "Massimo Vignelli",
"person_date": "Italian, active USA, 1931\u20132014",
"role_name": "Donor",
"role_display_name": "Donated by"
}
]
Here are my classes"
#JsonIgnoreProperties(ignoreUnknown = true)
public class ChObject {
#JsonProperty("participants")
private List<Participation> participants;
//Setters and getters
}
Here is the Participation class:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Participation {
private Role role;
private Participant participant;
//Setters and getters
}
Role class:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Role {
#JsonProperty("role_id")
private int role_id;
#JsonProperty("role_name")
private String role_name;
//Setters and getters
}
Participant class:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Participant {
private int person_id;
#JsonProperty("person_name")
private String person_name;
#JsonProperty("person_date")
private String person_date;
//Setters and getters
}
The issue I'm running into is that I can't figure out how to get the "person_name" and "person_date" properties into the Participant class or the "role_id" and "role_name" properties into the Role class from the Participation class.
The Participation class has access to all of those properties, but I can't seem to assign them to the properties of both the Participant and Roles classes.
Thanks for your help.
Sorry if I'm not 100% clear with everything.
Your class structure needs to match the structure of the JSON document, which is 1 object that contains a single field of type List<Participant>, and each Participant has those 6 properties.
You can move the data to those other classes that you have, after you de-serialize it correctly.
The correct classes would be:
public class ChObject {
#JsonProperty("participants")
List<Participant> participants;
// setters & getter omitted
}
public class Participant {
#JsonProperty("person_id")
private String id;
#JsonProperty("role_id")
private String roleId;
#JsonProperty("person_name")
private String name;
#JsonProperty("person_date")
private String date;
#JsonProperty("role_name")
private String roleName;
#JsonProperty("role_display_name")
private String roleDisplayName;
// setters & getters omitted
}
Also, notice how it is not necessary to match the java field name with the name of the property, since you specify its JSON name in the JsonProperty annotation.

Categories

Resources