Best practice for DTO classes that contain complex objects - java

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)

Related

Overriding #JsonProperty in a nested property

I have 2 classes:
class Customer {
. . .
#JsonProperty("customer_address")
private Address address;
}
and
class Company {
. . .
#JsonProperty("company_address")
private Address address;
}
The structure of the Address object is the same, both for company and customer, but unfortunately my JSON counterpart uses different JSON property names in the two cases, like
class Address { // in Customer
#JsonProperty("customer_city")
private String city;
}
class Address { // in Company
#JsonProperty("company_city")
private String city;
}
I'm wondering, but I miss how, if I can "override" the JsonProperty annotation in Address from the enclosing Customer/Company, so to have one only class.
Any suggestion?

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;
}

List denormalization with morphia

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.

Mapstruct ignore target nested property mapping

I have following DTO and Domain objects. I am using Mapstruct to copy domain object to DTO object.
public class AddressDomain {
private String street;
private Telephone telephone;
}
public class CompanyDomain{
private String id;
private Address address;
}
public class AddressDTO {
private String street;
private Telephone telephone;
}
public class CompanyDTO{
private String id;
private Address address;
}
Mapping Domain to DTO using below Mapper. i don't want to map telephone property from domain to DTO. How to do that? i tried providing nested target property in mapping ignore but it gives error:
public interface CompanyMapper {
//**below line gives error**
#Mapping(target = "address.telephone", ignore=true)
CompanyDTO map(AddressDTO dto);
}
Your current definition maps an address into a company object which doesn't seem right. You need to declare two methods, one for mapping addresses and one for mapping companies (whose generated implementation will in turn invoke the address mapping method):
public interface CompanyMapper {
CompanyDTO map(Company company);
#Mapping(target="telephone", ignore=true)
AddressDTO map(Address address);
}

#Embedded beans as final attribute?

We are using some #Embeddable beans within some JPA Entities for better code structure and reuse. What I'm wondering is: every example I come across provides setters and getters for the #Embedded objects. Why? I tried just having them as final fields - that works, too, and makes much sense in our case, since the embedded stuff is always present. Is there some disadvantage of this that I am not aware of?
For example: usually it is done that way:
#Embeddable
public class Address {
// ...
}
#Entity
public class Person {
#Embedded
private Address address;
public void setAddress(Address address) {
this.address = address;
}
public Address getAddress() {
return address;
}
}
Is there any trouble when I write Person this way, when there is always an Address:
#Entity
public class Person {
#Embedded
private final Address address = new Address();
public Address getAddress() {
return address;
}
}
You cannot persist final or static fields, and that applies whether embedded or non-embedded. The JPA spec is very clear about that, as are documents for the different JPA providers.
JPA Spec $2.1
The entity class must not be final. No methods or persistent instance
variables of the entity class may be final.

Categories

Resources