Very often I have a new entity that I would like to persist if it is to be considered "not equals" to any other already persisted, otherwise I would like to update the values of the fields that are not to be considered in the @override equals() method defined in the entity. In the new entity the key field is not valorized (very often it is an id @GeneratedValue(strategy = GenerationType.AUTO).
I started to write a method that could be used in these cases ... but I have problems to make it:
any help or suggestions?
Here is my first idea:
public abstract class JpaDao<T, PK extends Serializable> implements IDao<T, PK> {
protected Class<T> persistentClass;
protected String persistentName = "";
EntityManager em;
public JpaDao(EntityManager em) {
this();
this.em = em;
}
@SuppressWarnings("unchecked")
public JpaDao() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
// (***) Added from http://www.jroller.com/greenhorn/entry/uberdao_for_jpa
Annotation[] annotations = persistentClass.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof Entity) {
persistentName = ((Entity) annotation).name();
break;
}
}
if (persistentName.equals("")) {
persistentName = persistentClass.getSimpleName();
}
// End (***)
}
protected EntityManager getEntityManager() {
//return JpaUtility.currentEntityManager();
return this.em;
}
//HERE IS THE NEW METHOD - ONLY TO GIVE AN IDEA OF WHAT I WOULD LIKE TO DO!!!
//I suppose to have as a parameter the new detached entity that I want to save as new or merge with an already persisted one that is equals to this one (for the point of view of the @override equals() method implemented in the entity itself)
public T saveOrUpdate(T entity) {
List<T> entities = listByExample(entity, null, false);
if (entities.isEmpty()) {
//no entity found similar to this one
persist(entity);
} else {
//see if ,among the founded persisted entities, there is one to be considered equals to the one passed as parameter
for (T singleEntity: entities) {
if (singleEntity.equals(entity)) {
///????? how can I do to update the values of the fields of the singleEntity with the values of the entity parameter and let it persisted?????
......
}
}
}
return entity;
}
I'm waiting for suggestions or some link where I can find a method that can do what I need!!!
Kind regards
Enzo
P.S.
Here there are some explanations related to merge that I found and that I think useful ....
//http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/objectstate.html
Merging in EJB3 is similar to the saveOrUpdateCopy() method in native Hibernate. However, it is not the same as the saveOrUpdate() method, the given instance is not reattached with the persistence context, but a managed instance is returned by the merge() method.
//http://forum.springsource.org/archive/index.php/t-36064.html
The difference in laymen's terms between JPA's merge and Hibernate's saveOrUpdate is that saveOrUpdate copies the newly managed persistent state onto the object passed into the method, and merge does not.
The merge operation is clever enough to automatically detect whether the merging of the detached instance
has to result in an insert or update.
In other words, you don't have to worry about passing a new instance (and not a detached instance) to merge(),
the entity manager will figure this out for you:
/*
// In the first entity manager
Cat cat = firstEntityManager.find(Cat.class, catID);
// In a higher layer of the application, detached
Cat mate = new Cat();
cat.setMate(mate);
// Later, in a new entity manager
secondEntityManager.merge(cat); // update existing state
secondEntityManager.merge(mate); // save the new instance*/