why not hierarchy from entity to create dto? - java

Is there any reason to do not use hierarchy from an entity/model in order to create a dto/form object which help you to hold form search fields?
This is not a big system and these approach will help us to create real dto later if it is needed.
Our models are simple POJO's with almost any logic, maybe some validation logic but that would be valid also for the DTO.
I do not make sense to create a new DTO object with all the fields.
public class User {
private String name;
private String email;
private Date onboardingDate;
public User() {}
public User(String name, String email, Date onboardingDate) {
this.name = name;
this.email = email;
this.onboardingDate = onboardingDate;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Date getOnboardingDate() { return onboardingDate; }
public void setOnboardingDate(Date onboardingDate) { this.onboardingDate = onboardingDate; }
}
my DTO class, I can use it for use creation and for search purpose.
public class UserDTO extends User {
private Date fromDate;
private Date toDate;
public Date getFromDate() { return fromDate; }
public void setFromDate(Date fromDate) { this.fromDate = fromDate; }
public Date getToDate() { return toDate; }
public void setToDate(Date toDate) { this.toDate = toDate; }
public User convertToEntity() {
return new User(super.getName(), super.getName(), super.getOnboardingDate());
}
}
Thanks fox!

Usually, a DTO will be a subset of the entity data or also contain data from other associations in sub-DTOs or directly embedded in that DTO. If the DTO extends the entity, a user of a DTO object will have the possibility to invoke a getter to access all that state.
If your DTO is really a DTO, it will only have a subset of the data, but by extending from the entity, it might happen by accident that you access data that wasn't part of the subset that was loaded.
Imagine your user entity has detailed contact and address information. For one use case, you need that data, but for another you don't. It would not make sense to expose getters/setter for state that isn't there, would it? This is why one usually creates a separate DTO class for that purpose. You can still work with the entity type if you want to persist/update data, but even for these use cases, people sometimes tend to use DTOs because the persistent state does not necessarily represent the state which can be updated in a use case. This is especially important when you have state for e.g. denormalizations in your persistent state or cross cutting concerns like statistics or audit data.
If your model is so simple and will stay this way, then just use the entity model. If in 90% of the your use cases you need all data anyway, there is nothing you can gain from using DTOs.
Considering you have the need to create a subset of the entity state for your use cases I can only recommend you not to extend from the entity model and really just model what your use case requires. Never expose accessors to state that isn't there in DTOs. That will save you hours of debugging later.
Of course you could use your DTO for filter purposes, that's what is usually called filter by example, but you will notice that this has certain limits and quirks, so at some point you will need a different approach.
You can make use of a library that I develop called Blaze-Persistence Entity Views which allows you to create DTOs as interfaces. This is not only an easier way to model DTOs, but it will also perform better because it will only fetch the state really necessary for the desired representation.

Related

Replace String via Java Spring Annotation

I need to replace or remove some chars from user input
Is is possible declare annotation for change value after set?
for example, I have UserDTO class with username field. I want to change Unicode characters.
Please note that I using Spring Data + Web Service
#PostMapping("/register")
public RestResult register(#Valid #RequestBody UserDTO userDTO){
...
}
There are two approaches for this.
You can write the setter for the username object to handle this logic. The caveat of this is any username value passed through your setter will go through your String massaging.
public class UserDTO implements Serializable {
#JsonProperty("username")
private String username;
public void setUsername(String username) {
this.username = username.replace("A", "B");
}
public String getUsername() {
return this.username;
}
}
Another possible way of doing this is by using the #JsonCreator annotation provided by Jackson.
You'll need to keep in mind that this will become the deserialization strategy across all objects using the UserDTO object. But considering that you are looking to swap out unicode(most likely to an internal readable format) I would imagine that this would fit your use case.
public class UserDTO implements Serializable {
private String username;
#JsonCreator
public UserDTO(#JsonProperty("username") String username) {
this.username = username.replace("A", "B");
}
public String getUsername() {
return this.username;
}
}
So when passed through into your method, "ABC" will resolve to "BBC". This may be the preferred approach in your case, since it would give you the flexibility to adjust the object when needed without going through your username String cleaning. Objects created by serialization and constructor will go through the cleaning, but the setter will take the value as is. It's easy to get bit by logic in getters and setters.

In JPA mapping class to primitive

I want to mapping a class to a primitive type
#Entity
#Table(name="PERSON")
public class Person implements Serializable {
...
private Email email = null;
...
#Column(name="email")
public Email getEmail() {
return email;
}
public void setEmail(Email email) {
this.email=email;
}
}
In this example I want to save the email like a String
I wish something like:
interface someInterface{
String getValue();
void setValue(String p);
}
Then if I implement this interface in Email it can be save and loaded transparently (I haven't find something like this).
I don't want to serialize the class
I use Email as a example, but I have in mind many other class, to little to be a whole entity.
Any idea?
JPA2.1 provides AttributeConverter which means that a field can be marked with a converter persisting it as, for example, a String. All JPA implementations have their own variant currently, but DataNucleus JPA provides the JPA2.1 feature already, see the foot of this page.
Make two variables. Email which is object and that you mark as #Transient and emailStr that you store in the database. The emailStr getter and setter should be private, and the getEmail creates the email object (lazily) based on the emailStr.
Another solution, if you have email in many entities is to create a custom UserType.
Just google hibernate UserType..
You can use converters in EclipseLink for this,
see,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Basic_Mappings/Default_Conversions_and_Converters
There's nothing stopping you from using String in your Classes as far as JPA is concerned. Or any other primitive type for that matter...
EDIT: You mean something like this hopefully
#Entity
#Table(name="PERSON")
public class Person implements Serializable {
...
private String email = null;
...
#Column(name="email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email=email;
}
}

Preferred way of declaring methods in a class

I am having a doubt with method creations in a class for setting information.
creating separate methods for setting each attribute
class Address{
private String name;
private String city;
public setName(String name) { ... }
public setCity(String name) { ... }
}
creating single method for setting all attributes
class Address{
private String name;
private String city;
public setAddress(String name,String city) { ... }
}
from above two ways which is preferable in memory point of view?
Common practice is to use JavaBean style
class Address {
private String name;
private String city;
public setName(String name){
this.name = name;
}
public String getName() {
return name;
}
public setCity(String city){
this.city = city;
}
public getCity() {
return city;
}
}
Another common practise, which is quite similar to you second approach is to create immutable object. Parameters are passed to constructor instead of big setter method.
class Address {
private final String name;
private final String city;
public Address(String name, String city) {
this.name = name;
this.city = city;
}
public String getName() {
return name;
}
public getCity() {
return city;
}
}
From memory point of view, difference would be that second example is setting all attributes in constructor and all those attributes are immutable. In general, object constructed this way are safer when used by multiple threads.
In second example, there is no need for synchronization. You'd need to handle synchronization/memory issues when multiple threads using standard JavaBean object.
I can't see how the two approaches would be any different memory-wise.
Choose the approach that makes most sense to have in the interface of the class.
I would recommend to go with approach 2 only if both properties are logically strongly related, or if there is some class invariant that you don't want to temporarily break (even temporarily).
In your Address example, I would definitely go with two setter methods, since when talking about addresses, the name and city are quite unrelated.
For methods in general I'd say that whether or not you split a method up in two has little effect on memory consumption. Each object doesn't get its own set of methods allocated. The memory containing the methods is shared between all instances of a class.
Rule of thumb: Strive to make the interface of your class clean and logical.
Why not to use method #2
Your second example is not recommended because if you added a new field to the Address class, then do you add it into the existing setter method or do you create a new setter method? If you add it into the existing setter method, then any classes that called that method would be broken. And if you created a new setter method, then it is confusing for anyone who wants to use that class why certain fields are grouped together that way while others are not.
Using a separate setter method for each field that you wish to expose
The common practice is to have a single setter method for each field in your class that you wish to expose (i.e. your first example). Whether or not this is a good practice is debatable because it forces a class to be mutable. It is best to make an object immutable, if possible, for a number of reasons.
Initializing your fields using a constructor
One way to make a class immutable is by getting rid of the setter methods and instead making your fields settable via your class constructor, as below. The downside to implementing it this way is that if your class has a lot of fields, it may potentially lead to large, unreadable constructor calls.
public class Address {
public String name;
public String city;
private Address(String name, String city) {
this.name = name;
this.city = city;
}
}
Initializing your fields using the Builder pattern
Below is a completely alternative implementation (inspired by this article) that is a variation of the Builder pattern. It simulates object mutability without sacrificing readability.
public class Address {
public String name;
public String city;
private Address() {}
private void setName(String name) {
this.name = name;
}
private void setCity(String city) {
this.city = city;
}
static class Builder {
private Address address = new Address();
public Builder name(String name) {
address.setName(name);
return this;
}
public Builder city(String city) {
address.setCity(city);
return this;
}
public Address build() {
return address;
}
}
}
With the above class, you could create an immutable instance of the Address class as follows:
Address address = new Address.Builder()
.name("Mansoor's address")
.city("Toronto")
.build();
Which approach uses more memory?
From a memory point of view, there shouldn't be any difference since the size of a class in memory is dependent on the fields in the class. Since all three implementations have the same fields, they should take the same amount of space in memory, regardless of which approach you use.
This is not a clear question. Do you mean, would you rather have two methods like setFoo(String) and setBar(int), or one method like setFooBar(String, int)? It really depends on whether these are logically different properties, in which case you want individual methods, or whether it often (or only) makes sense to set them together. You could provide both.
Neither has any impact on memory, no.
The JavaBean standard is to have getters and setters for each property: http://en.wikibooks.org/wiki/Java_Programming/Java_Beans. If you don't want to follow that standard convention, its what makes the most sense for your shop. As per other answers on this thread, there probably is a minimal memory delta, if any.
Nb.1 without a doubt.
And you don't write that code by hand, only declare your fields.
Then you let Eclipse do the rest for you.
In Eclipse use Source --> generate getters and setters.
A very similar construct as #2 is done in the objects constructor.
The updated question with regards to memory. Don't worry one second in production code for the memory difference between those two ways.
You generally write a setter and a getter method for each attribute.
I don't really see the case when one method is enough for setting all the attributes. In this case, all attributes should have the same value? Or you always would have to pass parameters for all attributes. Both cases are not really what you want. So you should clearly prefer your first approach.

What's the most object-oriented way to design an address book?

I am asking myself how to design an object-oriented address book in Java.
Let's say a contact can have several contact details, like addresses, phone numbers and e-mail addresses.
One way to implement this would be to give every contact an ArrayList for every type. But there must be a better and more object-oriented solution. What is it?
The most OOP suggestion I can give you is to create a class for every item/piece of information. For example:
public abstract class ContactInfo { /* ... */ }
public class Address extends ContactInfo { /* ... */ }
public class PhoneNumber extends ContactInfo { /* ... */ }
public class EmailAddress extends ContactInfo { /* ... */ }
public class Contact {
private String name;
private Set<ContactInfo> info;
// ...
}
and finally,
public class AddressBook {
List<Contact> contacts;
// ...
}
This may or may not be overkill for your specific case, but as a thought experiment, it's the way to go. It obviously takes care of the literal part of OOP — using objects — but also lays groundwork for encapsulation, abstraction and inheritance, which are closely related principles.
You're on the right track. The only thing I would do differently would be to use a List interface instead of an ArrayList collection to reference the contacts' attribute collections. This is advice based on the code-to-interfaces rule-of-thumb as described in this article and many others.
I don't think that's particularly un-object oriented. If your domain is such that a Person can have zero or more EmailAddresses, then you've almost exactly described the situation to use a list.
The only alternative approach I can think of would be to have fields such as
WorkEmail
PersonalEmail
OtherEmail1
OtherEmail2
OtherEmail3
but in my opinion that's worse, because:
You simply cannot support more than five email addresses (well, you could add more fields, but that increases the pain of the latter points and still imposes some finite limit.)
You're implying some extra semantics than may be present (what if the same address is used for work and personal? What if neither applies, can you just fill the Other ones? What if you don't know the purpose?)
You now have to test each field manually to see which is null, which is going to involve a non-trivial amount of duplication in Java. You can't use nice features like the enhanced-for loop to apply the same block to every email address, and you can't trivially count how many addresses there are
The list of properties that a Person has is now much less clean. I suppose you could package these properties into an EmailContactDetails class or something, but now you've got an extra level of indirection (more conceptual complexity) for no real gain.
So, if a person has a possibly-empty, unbounded list of email addresses, what's wrong with representing that as a list?
You can also use a Map, and then get specific values e.g. via myMap.get("emailAdress1") or iterate over the whole map like you would do with a list via myMap.entrySet().
One simple way to handle most of the use cases can be like this
public class AddressBook {
private Map<String, Contact> contacts;
AddressBook(){
contacts = new HashMap<String, Contact>();
}
public boolean addContact(Contact contact) {
if(contacts.containsKey(contact.getName())) {
System.out.println("Already exists");
return false;
}
contacts.put(contact.getName(), contact);
return true;
}
public boolean updateContact(Contact contact) {
contacts.put(contact.getName(), contact);
return true;
}
}
class Contact{
private String name;
private String email;
private String phone;
private Address address;
public Contact(String name) {
this.name = name;
}
public Contact(String name, String email, String phone, Address address) {
this.name = name;
this.email = email;
this.phone = phone;
this.address = address;
}
// getters and setters
#Override
public String toString() {
return "name is "+name+" and address is "+address;
}
}
class Address{
private String street1;
private String street2;
private String city;
private int zipcode;
public Address() {}
// getters and setters
#Override
public String toString() {
return "street1 is "+street1+" and zipcode is "+zipcode;
}
}

Is there any way to declare final fields for Hibernate-managed objects?

I'm just getting started with Hibernate, and all the examples I'm seeing so far look pretty much like the tutorial in the Hibernate documentation:
package org.hibernate.tutorial.domain;
import java.util.Date;
public class Event {
private Long id;
private String title;
private Date date;
public Event() {}
/* Accessor methods... */
}
Specifically: none of the fields are declared as final, and there must be a no-argument constructor so that the Hibernate framework can instantiate the class and set its fields.
But here's the thing - I really don't like making my classes mutable in any way whenever I can avoid it (Java Practices: Immutable Objects make a pretty strong argument for doing this). So is there any way to get Hibernate to work even if I were to declare each of the fields 'final'?
I understand that Hibernate uses Reflection to instantiate its classes and therefore needs to be able to invoke a constructor of some sort without taking the risk that it would pick the wrong constructor or pass the wrong value to one of its parameters, so it's probably safer to invoke the no-arg constructor and set each field one at a time. However, shouldn't it be possible to provide the necessary information to Hibernate so that it can safely instantiate immutable objects?
public class Event {
private final Long id;
private final String title;
private final Date date;
public Event(#SetsProperty("id") Long id,
#SetsProperty("title") String title,
#SetsProperty("date") Date date) {
this.id = id;
this.title = title;
this.date = new Date(date.getTime());
}
/* Accessor methods... */
}
The #SetsProperty annotation is of course fictitious, but doesn't seem like it should be out of reach.
Actually in JDK 1.5+ hibernate can handle (through reflection) changing final fields. Create a protected default constructor() that sets the fields to some defaults/null etc... Hibernate can and will override those values when it instantiates the object.
This is all possible thanks to changes to Java 1.5 memory model - the changes of interest (allowing final to be not so final) where made to enable serialization/deserialization.
public class Event {
private final Long id;
private final String title;
private final Date date;
// Purely for serialization/deserialization
protected Event() {
id = null;
title = null;
date = null;
}
public Event(Long id, String title, Data date) {
this.id = id;
this.title = title;
this.date = date;
}
/* Accessor methods... */
}
Immutable object means an object with no methods that modify its state (i.e. its fields). The fields needn't be final. So you can remove all mutators and configure Hibernate to use fields acces instead of accessors or you can just mark no-arg constructor and mutators as deprecated. It's a bit workaround but better that than nothing.
This sounds like it is not a use case for Hibernate, since many operations it performs concern mutable state:
merging objects
dirty state checking
flushing changes
That being said, if you're concerned about immutability you may choose to provide wrappers around your objects, with copy-constructors:
public class FinalEvent {
private final Integer id;
public FinalEvent(Event event) {
id = event.id;
}
}
It does mean extra work though.
Now that I'm thinking of it, hibernate sessions are usually thread-bound and this voids at least one the benefits of the final fields - safe publication.
What other the benefits of final fields are you looking for?
This one has been bugging me for a long time too. One idea I've been trying out recently is this - define read-only interfaces for your model classes and have your DAOs and any factories return those instead on the object. That means that even though the implementation is mutable, once it's left the DAO/factory object it can no longer be tweaked.
Like so:
public interface Grape {
public Color getColor();
}
public class HibernateGrapeDao {
public Grape findGrape(int grapeId) {
HibernateGrape grape = hibernate.find(...
return grape;
}
}
class HibernateGrape implements Grape {
....
}
May even want to keep the implementing classes package-private to the dao package, so nobody can fiddle with them directly. A bit more work, but probably helps keep things cleaner in the long run. And, obviously, be careful with the whole equality/identity business.
You may be able to accomplish the desired result by using a Builder pattern. I read a posting a while ago on the Hibernate Forums discussing the idea (though I never implemented it myself...)
Annotate your class with #Access(AccessType.FIELD) then you can make your fields final. Like this:
#Access(AccessType.FIELD)
public final class Event {
private final Long id;
private final String title;
private final Date date;
private Event() {
id = null;
title = null;
date = null;
}
public Event(Long id, String title, Date date) {
this.id = id;
this.title = title;
this.date = date;
}
}

Categories