Query performane & CascadeType.PERSIST
jc7442 Sep 7, 2005 5:52 AMExecution time may vary for the same query from something close to 0 to a few seconds accroding to the context (ie persistent object retrieves previously). Is it a bug ?
Following a sample of code to reprodroduce that problem:
@Entity() public class Protocol { ... @OneToMany(cascade = CascadeType.PERSIST) @JoinTable(table = @Table(name = "Protocol_Param"), joinColumns = { @JoinColumn(name = "relation_id") }, inverseJoinColumns = @JoinColumn(name = "position_id")) public List<Parameter> getParameters() { return parameters; } ... } @Entity() public class Parameter { ... }
I create a Protocol containg 500 parameters. Its id is 1. Then I execute following code using a stateless session bean:
@PersistenceContext(unitName = "myDBTest") private EntityManager manager; @TransactionAttribute(TransactionAttributeType.REQUIRED) public void sample() { long l0 = System.currentTimeMillis(); Protocol p = manager.find(Protocol.class, 1); // ((InjectedEntityManager)manager).getHibernateSession().evict(relation); long l11 = System.currentTimeMillis(); Query query = manager.createQuery("SELECT count(t) FROM Taxon t"); System.out.println(query.getSingleResult()); long l2 = System.currentTimeMillis(); System.out.println("Find = " + (l11 - l0) / 1000.0); System.out.println("Query = " + (l2 - l11) / 1000.0); System.out.println("Total = " + (l2 - l0) / 1000.0); }
-I invoke the session bean several time. Find is very quick (around 0.0xs), query s quite long (around 0.5s).
-If I evict from the session the object return by the find, query becomes very fast (around 0.0xs).
-If I change the mapping in the Protocol for the OneToMay relationship (I remove the cascade = CascadeType.PERSIST part of the annotation), query becomes very fast (around 0.0xs).
- If I comment the find method, query becomes very fast (around 0.0xs).
I have reproduce that with several kind of classes with a List containing a lot of objects and with CascadeType.PERSIST. In that case, no objects are persisted, they are just retrieved form DB. Moreover the fetch for the list is LAZY, consequently the size of the list should have no impact of the performance. But in that case it has a great impact (not on the find execution but on the query ???).
It looks like a bug in some cache.
This sample may look stupid, it is just something that I isolate from a real application.
The same impact on the execution time of the query may be seen, if a lot of object are persisted in the same JTA transaction.
I really suspect a bug in hibernate cache. I use JBoss4.0.3rc2, EJB3rc1 and mysql.
I can use workaround such as not use CascadeType.PERSISTENT in my collection, but it makes thinks harder to implement.
I can also evict objects from the session, but it is just a hook specific to hibernate (it is ,ot ejb3). Moreover it will make the source code harder to implmenent and not very reusable.
Has someone already see that problem ? Is it a bug ?
Due to that kind of bug my application has very poor performance even if each query execute separatly are fast.
Regards