[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, 2 months
[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, 2 months
[Hibernate-JIRA] Created: (HHH-6037) doesn't remove the orphan entry
by Premraj Motling (JIRA)
doesn't remove the orphan entry
-------------------------------
Key: HHH-6037
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6037
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.5.3
Environment: Hibernate 3.5.3, JPA 2, ORACLE 11g
Reporter: Premraj Motling
Hibernate don't delete the orphan entries with OneToOne even after set to null
@Entity
public class Foo{
@Id
private long foo_id;
private String name;
@OneToOne(mappedBy = "foo", orphanRemoval = true)
private FooProperties fooProperties;
}
@Entity
public class FooProperties{
@Id
private long fp_id;
private String phoneNumber;
@OneToOne
@JoinColumn(name = "foo_id", nullable = false)
private Foo foo;
}
and if I do -
Foo foo = entityManager.find(Foo.class, fooId);
foo.getFooProperties.setFoo(null);
foo.setFooProperties(new FooProperties("xxx-xxx-xxx"));
entityManager.merge(foo);
its not deleting the FooProperties
--
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, 2 months
[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, 2 months
[Hibernate-JIRA] Created: (HHH-6221) Hibernate throws AnnotationException on column used by multiple overlapping foreign keys
by Karsten Wutzke (JIRA)
Hibernate throws AnnotationException on column used by multiple overlapping foreign keys
----------------------------------------------------------------------------------------
Key: HHH-6221
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6221
Project: Hibernate Core
Issue Type: Bug
Components: annotations, core, entity-manager
Affects Versions: 3.6.0
Environment: Hibernate 3.6.0, HSQLDB 2, JavaSE (probably all Hibernate versions to date affected)
Reporter: Karsten Wutzke
Priority: Critical
Attachments: overlapping-fks-hib-broken.zip
Here's a view of the design:
!http://www.kawoolutions.com/media/postareas-min.png!
Simple logic: two tables use composite PKs and use a country_code column in the PK. PostAreas is a simple join table so its PK is comprised of the two linked tables' PK columns. Problem: both FKs in PostAreas use country_code to produce an overlap.
This is per se nothing special, but in the context of JPA it is: there may be only one writable mapping in the @JoinColumn annotations, all other must be set to read-only, that is _insertable = false, updatable = false_.
Here are the (incomplete) mappings (full SSCCE attached):
{code:java}
@Entity
@Table(name = "Zips")
@IdClass(value = ZipId.class)
public class Zip implements Serializable
{
@Id
@Column(name = "country_code")
private String countryCode;
@Id
@Column(name = "code")
private String code;
...
}
{code}
{code:java}
public class ZipId implements Serializable
{
private String countryCode;
private String code;
...
}
{code}
{code:java}
@Entity
@Table(name = "Cities")
@IdClass(value = CityId.class)
public class City implements Serializable
{
@Id
@Column(name = "country_code")
private String countryCode;
@Id
@Column(name = "state_code")
private String stateCode;
@Id
@Column(name = "name")
private String name;
...
}
{code}
{code:java}
public class CityId implements Serializable
{
private String countryCode;
private String stateCode;
private String name;
...
}
{code}
{code:java}
@Entity
@Table(name = "PostAreas")
@IdClass(value = PostAreaId.class)
public class PostArea implements Serializable
{
@Id
@Column(name = "country_code", insertable = false, updatable = false)
private String countryCode;
@Id
@Column(name = "state_code", insertable = false, updatable = false)
private String stateCode;
@Id
@Column(name = "zip_code", insertable = false, updatable = false)
private String zipCode;
@Id
@Column(name = "city_name", insertable = false, updatable = false)
private String cityName;
@ManyToOne
@JoinColumns(value = {
@JoinColumn(name = "country_code", referencedColumnName = "country_code"),
@JoinColumn(name = "zip_code", referencedColumnName = "code")
})
private Zip zip;
@ManyToOne
@JoinColumns(value = {
@JoinColumn(name = "country_code", referencedColumnName = "country_code", insertable = false, updatable = false), // <- !!!
@JoinColumn(name = "state_code", referencedColumnName = "state_code"),
@JoinColumn(name = "city_name", referencedColumnName = "name")
})
private City city;
...
}
{code}
{code:java}
public class PostAreaId implements Serializable
{
private String countryCode;
private String stateCode;
private String zipCode;
private String cityName;
...
}
{code}
Looking at PostArea.city (*scroll down in the PostArea code box!*): the @JoinColumn for country_code is set to read-only on City and to writable on Zip. However, when running this from a JavaSE test app Hibernate fails with an AnnotationException:
{code}
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: postareas] Unable to configure EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:374)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)
at tld.postareas.Main.main(Main.java:38)
Caused by: org.hibernate.AnnotationException: Mixing insertable and non insertable columns in a property is not allowed: tld.postareas.model.PostAreacity
at org.hibernate.cfg.Ejb3Column.checkPropertyConsistency(Ejb3Column.java:563)
at org.hibernate.cfg.AnnotationBinder.bindManyToOne(AnnotationBinder.java:2703)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1600)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:796)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:707)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3977)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3931)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1368)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345)
at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1477)
at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1096)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:278)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:362)
... 4 more
{code}
When mapping a table that uses the same column in two or more foreign keys, only one of the relationships' @JoinColumn annotations may be tagged as writable. However, mixing read-only and writable in a multi-column relationship *must* be supported.
--
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, 2 months
[Hibernate-JIRA] Created: (HHH-6349) AuditJoinTable rows missing when detached entities with collections are merged into the persistence context
by Erik-Berndt Scheper (JIRA)
AuditJoinTable rows missing when detached entities with collections are merged into the persistence context
-----------------------------------------------------------------------------------------------------------
Key: HHH-6349
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6349
Project: Hibernate Core
Issue Type: Bug
Components: envers
Affects Versions: 4.0.0.Beta1, 3.6.5
Reporter: Erik-Berndt Scheper
Assignee: Erik-Berndt Scheper
Given an Entity that is audited by Envers, which contains more than one collection (e.g. two Lists); for example
{code:title=MultipleCollectionEntity .java|borderStyle=solid}
Entity
@org.hibernate.envers.Audited
public class MultipleCollectionEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", length = 10)
private Long id;
@Version
@Column(name = "VERSION", nullable = false)
private Integer version;
@Column(name = "TEXT", length = 50, nullable = false)
private String text;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "MCE_ID", nullable = false)
@org.hibernate.envers.AuditJoinTable(name = "MCE_RE1_AUD", inverseJoinColumns = @JoinColumn(name = "RE1_ID"))
private List<MultipleCollectionRefEntity1> refEntities1 = new ArrayList<MultipleCollectionRefEntity1>();
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "MCE_ID", nullable = false)
@org.hibernate.envers.AuditJoinTable(name = "MCE_RE2_AUD", inverseJoinColumns = @JoinColumn(name = "RE2_ID"))
private List<MultipleCollectionRefEntity2> refEntities2 = new ArrayList<MultipleCollectionRefEntity2>();
{code}
Envers stores the audit information for additions and deletions to these Lists in AuditJoinTables (MCE_RE1_AUD and MCE_RE2_AUD). This process is driven by the Hibernate collection events; to be exact by the difference between the current contents of the collection (using event.getCollection()) and the contents of the stored snapshot of this collection (using collectionEntry.getSnapshot()).
This works fine as long as the given entity is available in the current persistence context.
Unfortunately, this is not the case when detached entities are merged back into the persistence context.
In this case, the end result is that audit information is stored in the MultipleCollectionEntity_AUD table, in the MultipleCollectionRefEntity1_AUD table and the MultipleCollectionRefEntity2_AUD table. However, the AuditJoinTable rows are missing.
Effectively this means that the rows in MultipleCollectionRefEntity2_AUD are dangling and that the audit information when refEntities were added or deleted to the refEntities1 and refEntities2 collections has been irretrievably lost.
I have prepared Envers test cases for the 3.6.x and 4.0.x versions and will be adding them shortly.
--
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, 2 months
[Hibernate-JIRA] Created: (HHH-6473) Hibernate hbm2ddl doesn't create Indexes from @Index annotations on @ManyToMany relations
by Samuel Mendenhall (JIRA)
Hibernate hbm2ddl doesn't create Indexes from @Index annotations on @ManyToMany relations
-----------------------------------------------------------------------------------------
Key: HHH-6473
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6473
Project: Hibernate Core
Issue Type: New Feature
Components: annotations
Affects Versions: 4.0.0.Beta4
Reporter: Samuel Mendenhall
Fix For: 4.x
When generating the SQL schema with Hibernate using the hbm2ddl feature the generation of indexes on ManyToMany relationships like the following is not working:
@ManyToMany()
@JoinTable(name = "REL_FOO_BAR", joinColumns = @JoinColumn(name = "FOO_FK"), inverseJoinColumns = @JoinColumn(name = "BAR_FK"))
@Index(name = "FOO_BAR_IDX")
The created SQL schema doesn't include an index named USER_ROLES_IDX. With other relation types (ManyToOne, etc.) the index is created as expected.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 2 months
[Hibernate-JIRA] Created: (HHH-2223) BatchFetchQueue.getXXXBatch() cache check impeding batch fetching
by Joel Caplin (JIRA)
BatchFetchQueue.getXXXBatch() cache check impeding batch fetching
-----------------------------------------------------------------
Key: HHH-2223
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2223
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.0.ga
Environment: 3.2.0GA, Mac OS X/Solaris 10, Sybase 12.5/HSQLDB
Reporter: Joel Caplin
Priority: Minor
Attachments: testcase.tar
I have attached a test case which demonstrates the issue at hand by implementing a cheap data model: Pub >---|- Manager -|--< Employee
Pub and Employee are uncached; Manager is cached (tried under both Eh and the non-prod HashMap implementation). All associations are lazy. The test case has a default batch size of 10 and uses hsqldb to demonstrate the problem - which was diagnosed against Sybase.
When BatchFetchQueue.getXXXBatch() is invoked, it does not load any objects it finds in the second level cache - it merely acknowledges their presence by logging to INFO (isCached()). This in turn means that any child associations in that cached object will not have a proxy created for them.
Suppose we want to find all the employees of the pubs in our database. We choose to do this by loading all the Pubs ("FROM Pub") and calling thePub.getManager().getEmployees() iteratively.
When the managers are in the second level cache, Hibernate issues 11 select statements: one to load the pubs and one for each distinct manager.
When the Managers are not in the cache, Hibernate issues 3 select statements: one to load the pubs, one to load the managers and one to load the employees.
A solution might be to load the object from the cache instead of just ignoring it?
--
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, 2 months