[Hibernate-JIRA] Created: (HHH-2891) Query cache fails on many-to-many select
by Oleg Efimov (JIRA)
Query cache fails on many-to-many select
----------------------------------------
Key: HHH-2891
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2891
Project: Hibernate3
Issue Type: Bug
Components: query-hql
Affects Versions: 3.2.5
Reporter: Oleg Efimov
I have two entities, User and Group, with many-to-many relation:
-------------------------------------------------------------------------------------------------- User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test.hibernate">
<class name="User" table="`USER`">
<id name="id" type="long" unsaved-value="null">
<column name="USER_ID" not-null="true"/>
<generator class="native"/>
</id>
<property name="login">
<column name="LOGIN" not-null="true" length="255"/>
</property>
<bag name="groups" table="USER_GROUP" lazy="false" cascade="none">
<key column="USER_ID"/>
<many-to-many class="Group" column="GROUP_ID"/>
</bag>
</class>
</hibernate-mapping>
-------------------------------------------------------------------------------------------------- Group.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test.hibernate">
<class name="Group" table="`GROUP`">
<id name="id" type="long" unsaved-value="null">
<column name="GROUP_ID" not-null="true"/>
<generator class="native"/>
</id>
<property name="name">
<column name="GROUPNAME" not-null="true" length="100"/>
</property>
<bag name="users" table="USER_GROUP" lazy="true" inverse="true" cascade="all-delete-orphan">
<key column="GROUP_ID"/>
<many-to-many class="User" column="USER_ID"/>
</bag>
</class>
<query name="Group.select.by.login" cacheable="true"><![CDATA[
select user.groups from User user where user.login=?
]]>
</query>
</hibernate-mapping>
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test.hibernate.User and test.hibernate.Group classes are just simple beans.
In Group.hbm.xml there is a query called "Group.select.by.login", it's intended to be cached. So I add corresponding properties to Hibernate configuraition:
--------------------------------------------------------------------------------------------------
properties.put("hibernate.cache.provider_class", "org.hibernate.cache.EhCacheProvider");
properties.put("hibernate.cache.use_query_cache", "true");
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Configuration has no extra parameters.
Then I'm trying to execute the query two times:
-------------------------------------------------------------------------------------------------- test fragment
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = null;
try {
session = sessionFactory.openSession();
Query query = session.getNamedQuery("Group.select.by.login");
List<Group> groups;
groups = query.setParameter(0, "admin").list(); // +++++++++++++++This list() returns list of two Group objects, ok +++++++++++++++
System.out.println("-----------------------------------------------------------------------------------");
for (Group group : groups) {
System.out.println(group.getName());
}
System.out.println("-----------------------------------------------------------------------------------");
groups = query.setParameter(0, "admin").list(); // +++++++++++++++This list() returns list of two nulls +++++++++++++++
System.out.println("-----------------------------------------------------------------------------------");
for (Group group : groups) {
System.out.println(group.getName());
}
System.out.println("-----------------------------------------------------------------------------------");
} finally {
if (session != null) {
session.close();
}
sessionFactory.close();
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The first query returns list of, in my case, two groups. The second query returns list of two nulls instead of the same list.
I've investigated the problem, and found the following:
Query return value is "user.groups", and during query analysis (org.hibernate.hql.ast.QueryTranslatorImpl:160) query return type is defined as "org.hibernate.type.BagType(test.hibernate.User.groups)". This seems to be the problem, as during query put operation org.hibernate.CollectionType.disassemble is called (org.hibernate.cache.StandardQueryCache:80), which simply returns null as owner is null.
If this query is not a misuse, then I think, something is to be done at the time of analysis, so that return type be somewhat different.
Thanks.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 1 month
[Hibernate-JIRA] Created: (HHH-4732) Update Teradata Dialect for Teradata 13.0
by David Repshas (JIRA)
Update Teradata Dialect for Teradata 13.0
-----------------------------------------
Key: HHH-4732
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-4732
Project: Hibernate Core
Issue Type: Improvement
Components: core
Affects Versions: 3.3.2
Environment: Hibernate 3.3.2/ Teradata JDBC Driver 13.0, Teradata Database 13.0
Reporter: David Repshas
Attachments: teradata.zip
Would like to update Teradata Dialect to work with Teradata Database 13.0.
I've include the following files with changes as noted:
org.hibernate.dialect.dialect.java
- added include of java.sql.statement
- added code to support the removal of temporary
files created when using referential integrity
The three new methods are:
public boolean supportsDropPreProcess()
public String performDropPreProcess(Statement stmt, String dropSql) throws SQLException
public void performDropPostProcess(Statement stmt, String dropSql) throws SQLException
==================================
org.hibernate.dialect.TeradataDialect.java
- added new include files
- modified registerFunction calls for "current_time" and "current_date"
- put registerKeyword list in alphabetical order and added keywords:
column,map,password,summary, type, value and year
- changed "getAddColumnString()" to return "Add"
- added new methods:
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter()
public String extractConstraintName(SQLException sqlex)
public boolean supportsNotNullUnique()
public boolean supportsExpectedLobUsagePattern()
public boolean supportsUnboundedLobLocatorMaterialization()
public boolean supportsDropPreProcess()
public String performDropPreProcess(Statement stmt, String dropSql) throws SQLException
public void performDropPostProcess(Statement stmt, String dropSql) throws SQLException
==================================
org.hibernate.tool.hbm2ddl.SchemaExport
- added hooks for new methods:
supportsDropPreProcess,performDropPreProcess and performDropPostProcess
==================================
Also made some changes to some of the files in testsuite:
=============================================
test/hql/astParserLoadingTest.java
- Add instance check of TeradataDialect to get correct behavior
=============================================
test/legacy/foobartest.java
- Add instance check of TeradataDialect to get correct behavior
- modified SQL: Teradata requires "<>" rather than "!="
=============================================
test/typeParameters\typeparametertest.java
-needed to disable these tests as Teradata locking was causing
a deadlock situation when they run
=============================================
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 1 month
[Hibernate-JIRA] Created: (HHH-3795) Unexpected behaviour of saveOrUpdate() for associations with delete-orphan
by Fabian Dankof (JIRA)
Unexpected behaviour of saveOrUpdate() for associations with delete-orphan
--------------------------------------------------------------------------
Key: HHH-3795
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3795
Project: Hibernate Core
Issue Type: Improvement
Environment: Hibernate 3.2.6.GA, PostgreSQL 8.3
Reporter: Fabian Dankof
Hello there,
I think saveOrUpdate() behaves somewhat unexpected for associations with delete-orphan cascading style:
Prerequisite: Association is set to cascade="all,delete-orphan" and nullable=true
1) Within a single session (i.e. a transient object):
* Load parent
* Delete child
* saveOrUpdate()
Result: Child is deleted from DB, a DELETE statement was issued
2) Across multiple session (i.e. a detached object):
* Have parent with valid ID, but empty list/set of children
* saveOrUpdate()
Result: Child is not deleted from DB, an UPDATE statement is issued which sets FK of child to 'null'
3) like 2) but nullable is FALSE
Result: Nothing happens.
With merge() everything works as expected for detached and transient instances. I would either expect saveOrUpdate() to
completely disregard DELETE statements OR behave similar to merge(). At least the different results of case 1) and 2)
are pretty confusing.
Best regards,
Fabian
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 1 month
[Hibernate-JIRA] Created: (HHH-3628) Hilo optimizer problem in case of multiple threads accessing the sequence table
by Montagnon Cyril (JIRA)
Hilo optimizer problem in case of multiple threads accessing the sequence table
-------------------------------------------------------------------------------
Key: HHH-3628
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3628
Project: Hibernate Core
Issue Type: Bug
Affects Versions: 3.2.6
Environment: Sybase
Reporter: Montagnon Cyril
If 2 (or more) threads access the table storing the ids, this optimizer won't work and will try to insert entities with twice the same idea.
The problem is the way the HiLoOptimizer class generates the id :
public synchronized Serializable generate(AccessCallback callback) {
if ( lastSourceValue < 0 ) {
lastSourceValue = callback.getNextValue();
while ( lastSourceValue <= 0 ) {
lastSourceValue = callback.getNextValue();
}
hiValue = ( lastSourceValue * incrementSize ) + 1;
value = hiValue - incrementSize;
}
else if ( value >= hiValue ) {
lastSourceValue = callback.getNextValue();
hiValue = ( lastSourceValue * incrementSize ) + 1;
}
return make( value++ );
}
In the 'else if' part, the 'value' variable isn't reaffected, which means the current thread will try to insert entities with an id that has already been used by another thread. The value should be reset with hiValue - incrementSize.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 1 month
[Hibernate-JIRA] Created: (HHH-5267) NPE on Cascade after switch to hibernate 3.5
by Krzysztof Kowalczyk (JIRA)
NPE on Cascade after switch to hibernate 3.5
--------------------------------------------
Key: HHH-5267
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5267
Project: Hibernate Core
Issue Type: Bug
Components: annotations, core
Environment: Hibernate 3.5.x
Reporter: Krzysztof Kowalczyk
Priority: Blocker
We use hibernate annotations and hibernate search in our project. After we moved to hibernate 3.5.2 (and 3.5.1 before that) we are having the following errors:
java.lang.NullPointerException
at org.hibernate.engine.EntityEntry.getLoadedValue(EntityEntry.java:255)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:232)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.engine.Cascade.cascade(Cascade.java:127)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:376)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:350)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:425)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:362)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:338)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:154)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:145)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:655)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy67.initializePlacowka(Unknown Source)
In different place we have the same problem:
[java] java.lang.NullPointerException
[java] at org.hibernate.engine.EntityEntry.getLoadedValue(EntityEntry.java:255)
[java] at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:232)
[java] at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
[java] at org.hibernate.engine.Cascade.cascade(Cascade.java:127)
[java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.cascadeOnUpdate(DefaultSaveOrUpdateEventListener.java:376)
[java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:350)
[java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)
[java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:112)
[java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
[java] at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
[java] at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
[java] at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
[java] at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
[java] at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
[java] at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
[java] at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
[java] at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:451)
[java] at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
[java] at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
[java] at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
[java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
[java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
[java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
[java] at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
[java] at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
[java] at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
[java] at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:665)
The NPE is thrown because "loadedState" field is null. The exception seems to occur for instance when we have OneToOne with Cascade.DELETE_ORPHAN (or orphanRemoval="true"), CascadeType.SAVE_UPDATE and CascadeType.DELETE.
I will try to create a simple example to reproduce the problem.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 1 month
[Hibernate-JIRA] Created: (HHH-4910) L2 parent collection cache eviction when a child is added/updated/removed
by Julien Kronegg (JIRA)
L2 parent collection cache eviction when a child is added/updated/removed
-------------------------------------------------------------------------
Key: HHH-4910
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-4910
Project: Hibernate Core
Issue Type: Improvement
Components: core
Affects Versions: 3.3.1
Environment: Hibernate 3.3.1, DB2 390
Reporter: Julien Kronegg
Priority: Minor
Hibernate should automatically evict the collection cache an entity is persisted/updated/removed.
Some precisions:
- I'm not wanting to update the collection cache, evicting is fine
- Doing persisted/updated/removed operation by using the collection add/remove evicts the collection
- Doing persisted/updated/removed operation on the child entity does not evict the collection
h3. Test case
I have test case with a Parent entity which holds a OneToMany Set<Child> called 'children':
{code}
...
@Entity
@Table(...)
public class Parent {
@Id
private long id;
@OneToMany(mappedBy="parent", fetch=FetchType.LAZY)
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Child> children;
... getters and setters
}
@Entity
@Table(...)
public class Child {
@Id
private long id;
@ManyToOne()
private Parent parent;
... getters and setters
}
{code}
Level 2 cache is configured as follow:
- EhCache 1.6.2, default configuration, L2 cache activated
- entities are not cached
- the 'children' collection is cached
- no queries are cached
The L2 cache works as expected when reading the Parent's children collection size:
1. new EntityManager
2. loading myParent -> makes a SQL query on the Parent table
3. calling myParent.getChildren().size() -> makes a SQL query on the Child table
4. new EntityManager
5. loading myParent -> makes a SQL query on the Parent table (since entities are not cached)
6. calling myParent.getChildren().size() -> hit the L2 cache (no SQL queries)
The test case consists in
- persisting a new Child with a Parent
- updating a Child's Parent (i.e. changing its Parent for another Parent)
- deleting a Child with a Parent
When doing the test case by managing the Parent.children collection (e.g. myParent.getChildren().add(myNewChild)), the L2 cache works as expected:
the Parent.children collection is evicted from the L2 cache and the next myParent.getChildren().size() makes a SQL query.
But when doing the test case by managing the Child.parent, the L2 cache does not work as expected: the Parent.children collection is not evicted from L2 cache.
Example 1: persist
{code}
Parent myParent = em.find(Parent.class, 1);
System.out.println(em.find(Parent.class, 1).getChildren().size()); // by now, the Parent has 0 children
Child myChild = new Child();
myChild.setParent(myParent);
em.persist(myChild);
em.flush();
em = ... // get a new EntityManager
System.out.println(em.find(Parent.class, 1).getChildren().size()); // still 0 children
{code}
--> myParent.children has still the previous size (i.e. 0 instead of 1)
Example 2: update
{code}
Child myChild = em.find(Child.class, 1);
Parent myParent = em.find(Parent.class, 1);
em.refresh(myParent); // refresh to be sure to bypass the L2 collection cache
System.out.println(em.find(Parent.class, 1).getChildren().size()); // by now, the Parent has 1 children
myChild.setParent(null);
em.flush();
em = ... // get a new EntityManager
System.out.println(em.find(Parent.class, 1).getChildren().size()); // still 1 children
{code}
-> myParent.children has still the previous size (i.e. 1 instead of 0)
Example 3: remove
{code}
Child myChild = em.find(Child.class, 1);
Parent myParent = em.find(Parent.class, 1);
em.refresh(myParent); // refresh to be sure to bypass the L2 collection cache
System.out.println(em.find(Parent.class, 1).getChildren().size()); // by now, the Parent has 1 children
em.remove(myChild);
em.flush();
em = ... // get a new EntityManager
System.out.println(em.find(Parent.class, 1).getChildren().size()); // still 1 children and raise EntityNotFoundException
{code}
-> myParent.children has still the previous size and a EntityNotFoundException is raised because the deleted cached element cannot be found in the database
This problem is also reported here:
- http://stackoverflow.com/questions/1505940/hibernate-ehcache-evicting-col...
- http://stackoverflow.com/questions/1470502/hibernate-clean-collections-2n...
And is more or less related to the following JIRA issues:
- http://opensource.atlassian.com/projects/hibernate/browse/HHH-496
- http://opensource.atlassian.com/projects/hibernate/browse/HHH-1444
- http://opensource.atlassian.com/projects/hibernate/browse/HHH-1913
h3. Expected behavior
For these test cases, I expected the L2 cache behavior to be as follow:
1. when a new Child is persisted/removed, the collection which own it is evicted from the collection cache
This means:
{code}
mySessionFactory.evictCollection("Parent.children", myChild.getParent().getId());
{code}
2. when a Child parent changes, the collection which was owning the child AND the collection which own the child are evicted from the collection cache
This means:
{code}
mySessionFactory.evictCollection("Parent.children", myChildBeforeChange.getParent().getId());
mySessionFactory.evictCollection("Parent.children", myChild.getParent().getId());
{code}
This behavior would probably be implemented in the following classes:
- org.hibernate.action.EntityInsertAction
- org.hibernate.action.EntityDeleteAction
- org.hibernate.action.EntityUpdateAction
See http://opensource.atlassian.com/projects/hibernate/browse/HHH-1913 for a patch temptative (incomplete: some code is missing)
h3. Workaround:
When working with JPA/Hibernate annotations, the above behavior can be implemented using reflection as such (pseudo-code):
1. listen to persist/update/remove entity events: @EntityListeners, @PostPersist, @PostRemove, @PreUpdate
2. in the @PostPersist/@PostRemove entity event listener:
a. get all @ManyToOne fields/properties of the entity class (i.e. 'children' property of Child) and get the mapped class (i.e. Parent)
b. get the collectionName (i.e. field name of Parent class with @OneToMany annotation and a type of Collection<Child>)
c. build the collectionRole as Parent.class.getName()+"."+collectionName
d. get the entityKey as the identifier of the field found in (a)
e. call mySessionFactory.evictCollection(collectionRole, entityKey)
3. in the @PreUpdate entity event listener:
a. get all @ManyToOne fields/properties of the entity class (i.e. 'children' property of Child) and get the mapped class (i.e. Parent)
b. get the collectionName (i.e. field name of Parent class with @OneToMany annotation and a type of Collection<Child>)
c. build the collectionRole as Parent.class.getName()+"."+collectionName
d. get the entityKey as the identifier of the field found in (a) for the current entity
e. get the previousEntityKey as the identifier of the field found in (a) for the previous entity
f. if entityKey!=previousEntityKey then
call mySessionFactory.evictCollection(collectionRole, entityKey)
call mySessionFactory.evictCollection(collectionRole, previousEntityKey)
We tested this workaround with success. The event listener lasts for about 3 us/call (microseconds) which is okay.
Advantages:
- easy for the programmer (no need for entityManager.refresh(myParent) or mySessionFactory.evictCollections())
- clean code
Disadvantages:
- @EntityListeners annotation to be put on every entity
- requires Hibernate configuration by annotations on entities (does not work with XML configuration)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 1 month