When a object has a collection and a element of this collection is removed or insert a new, the hibernate cache will not be updated and if it does a search of this object, the removed element of collection in object will appear, but it's wrong!!! cause was removed!!!, hibernate is not updating the own cache.
As a workaround, update manually the object collection.
my question is:
the behavior of hibernate is right in this situation?
how I get the object with a consistent state from the method get in hibernate?
bellow I posted a sample code of this situation,
Code:
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class Main {
public static void main(String[] args) {
SessionFactory sf = createSessionFactory();
Session s = sf.openSession();
Transaction tx = s.beginTransaction();
try {
Master master = new Master();
master = (Master)s.merge(master);
Item i = new Item();
i.setMaster(master);
s.merge(i);
Master data = (Master)s.get(Master.class, master.getId());
System.out.println(data.getItens().size());
} finally {
tx.rollback();
}
}
private static SessionFactory createSessionFactory(){
Configuration configuration = new Configuration();
configuration.addAnnotatedClass(Master.class);
configuration.addAnnotatedClass(Item.class);
configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
configuration.setProperty("hibernate.show_sql", "true");
configuration.setProperty("hibernate.hbm2ddl.auto","create");
configuration.setProperty("hibernate.connection.url", "jdbc:h2:mem:xxx;DB_CLOSE_DELAY=1000");
configuration.setProperty("hibernate.connection.driver_class", "org.h2.Driver");
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
}
@Entity
class Master {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
@OneToMany(mappedBy="master", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
private List<Item> itens = new ArrayList<Item>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<Item> getItens() {
return itens;
}
public void setItens(List<Item> itens) {
this.itens = itens;
}
}
@Entity
class Item {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
@ManyToOne()
@JoinColumn(name="master", referencedColumnName="id")
private Master master;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Master getMaster() {
return master;
}
public void setMaster(Master master) {
this.master = master;
}
}