[Hibernate-JIRA] Created: (HHH-2498) Lazy Inverse Map Bug?
by CannonBall (JIRA)
Lazy Inverse Map Bug?
---------------------
Key: HHH-2498
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2498
Project: Hibernate3
Type: Bug
Versions: 3.2.1, 3.2.2
Environment: Hibernate 3.2.2, Java5, MySQL 5 (InnoDB)
Reporter: CannonBall
Priority: Minor
Mapping documents:
<hibernate-mapping>
<class name="scratchpad.hibernate.A">
<id name="id">
<generator class="assigned"/>
</id>
<map name="bs" cascade="all-delete-orphan" inverse="true">
<key column="aId"/>
<map-key type="long" column="cId"/>
<one-to-many class="scratchpad.hibernate.B"/>
</map>
</class>
<class name="scratchpad.hibernate.B">
<id name="id">
<generator class="assigned"/>
</id>
<many-to-one name="a" class="scratchpad.hibernate.A" column="aId"/>
<many-to-one name="c" class="scratchpad.hibernate.C" column="cId" not-null="true"/>
</class>
<class name="scratchpad.hibernate.C">
<id name="id">
<generator class="assigned"/>
</id>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
long aId = 1l;
long bId = 2l;
long cId = 3l;
SessionFactory factory = new Configuration().configure()
.buildSessionFactory();
try {
Session s = factory.openSession();
try {
Transaction tx = s.beginTransaction();
try {
C c = new C(cId);
s.save(c);
A a = new A(aId);
B b = new B(bId);
b.setC(c);
b.setA(a);
a.getBs().put(cId, b);
s.save(a);
tx.commit();
} catch (Exception e) {
try {
tx.rollback();
} catch (Exception e2) {
// do nothing
}
throw e;
}
} finally {
s.close();
}
s = factory.openSession();
try {
Transaction tx = s.beginTransaction();
try {
A a = (A) s.load(A.class, aId);
a.getBs().remove(cId);
tx.commit();
} catch (Exception e) {
try {
tx.rollback();
} catch (Exception e2) {
// do nothing
}
throw e;
}
} finally {
s.close();
}
} finally {
factory.close();
}
Name and version of the database you are using: MySQL 5.0.33
The generated SQL (show_sql=true):
Hibernate: select b_.id, b_.aId as aId1_, b_.cId as cId1_ from B b_ where b_.id=?
Hibernate: insert into C (id) values (?)
Hibernate: insert into A (id) values (?)
Hibernate: insert into B (aId, cId, id) values (?, ?, ?)
Hibernate: select a0_.id as id0_0_ from A a0_ where a0_.id=?
Hibernate: select bs0_.aId as aId1_, bs0_.id as id1_, bs0_.cId as cId1_, bs0_.id as id1_0_, bs0_.aId as aId1_0_, bs0_.cId as cId1_0_ from B bs0_ where bs0_.aId=?
I've been having a confusing problem shown above, whereby A has a Map of Bs indexed using the id from an association with C. This Map is inversely mapped for A and with 'Cascade Delete Orphan'. In the second opened session above, where B is removed from A's Map and thus orphaned, B will not be deleted. I have observed B is only deleted if I either set 'lazy="false"' for A's Map or make an interaction with A's Map in the code (before B's removal) like 'a.getBs().get(cId)'. I suspect the lazy intializer is not initializing correctly in the above scenario.
The above scenario does not happen if A's Map is not inversely mapped but B's many-to-one with A is.
Can somebody shed some light on whether this is me using Hibernate incorrectly or is a bug?
--
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
15 years, 7 months
[Hibernate-JIRA] Created: (HHH-3504) Hibernate 3.3.1GA issue when using CGLIB
by Montagnon Cyril (JIRA)
Hibernate 3.3.1GA issue when using CGLIB
----------------------------------------
Key: HHH-3504
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3504
Project: Hibernate Core
Issue Type: Bug
Affects Versions: 3.3.1
Environment: Database : hsqldb/Sybase
Reporter: Montagnon Cyril
When forcing hibernate to use CGLIB (by the way javassist is still slower than CGLib), I get the following exception (at the end of the post)
It seems that the repackaging of the CGLIB project (hibernate-cglib-repack) doesn't behave as expected :
Shouldn't it look up for the org.hibernate.repackage.cglib.proxy.Callback class instead of the net.sf.cglib.proxy.Callback class.
java.lang.NoClassDefFoundError: net.sf.cglib.proxy.Callback
at org.hibernate.repackage.cglib.proxy.Enhancer.class$(Enhancer.java:68)
at org.hibernate.repackage.cglib.proxy.Enhancer.getCallbacksSetter(Enhancer.java:627)
at org.hibernate.repackage.cglib.proxy.Enhancer.setCallbacksHelper(Enhancer.java:615)
at org.hibernate.repackage.cglib.proxy.Enhancer.setThreadCallbacks(Enhancer.java:609)
at org.hibernate.repackage.cglib.proxy.Enhancer.registerCallbacks(Enhancer.java:578)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.getProxyInstance(CGLIBLazyInitializer.java:133)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.getProxy(CGLIBLazyInitializer.java:116)
at org.hibernate.proxy.pojo.cglib.CGLIBProxyFactory.getProxy(CGLIBProxyFactory.java:72)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:402)
at org.hibernate.persister.entity.AbstractEntityPersister.createProxy(AbstractEntityPersister.java:3483)
at org.hibernate.event.def.DefaultLoadEventListener.createProxyIfNecessary(DefaultLoadEventListener.java:298)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:219)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:822)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:815)
at org.springframework.orm.hibernate3.HibernateTemplate$3.doInHibernate(HibernateTemplate.java:566)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.load(HibernateTemplate.java:560)
at org.springframework.orm.hibernate3.HibernateTemplate.load(HibernateTemplate.java:554)
at north.stardust2.core.test.unit.dao.listed.IndexCompositionDaoTest.findIndexCompositionByListedIndexAt(IndexCompositionDaoTest.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.junit.internal.runners.CompositeRunner.runChildren(CompositeRunner.java:33)
at org.junit.runners.Suite.access$000(Suite.java:26)
at org.junit.runners.Suite$1.run(Suite.java:93)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.runners.Suite.run(Suite.java:91)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
--
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
15 years, 7 months
[Hibernate-JIRA] Created: (HHH-3523) org.hibernate.id.enhanced.SequenceStyleGenerator causes org.hibernate.MappingException with SAPDB and DB2Dialect
by Damir Malenicic (JIRA)
org.hibernate.id.enhanced.SequenceStyleGenerator causes org.hibernate.MappingException with SAPDB and DB2Dialect
----------------------------------------------------------------------------------------------------------------
Key: HHH-3523
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3523
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.3.1
Environment: Hibernate 3.3.1.GA
Generation of DDL scripts for DB2Dialect and SAPDBDialect
Reporter: Damir Malenicic
Attachments: db2-sapdb-bug.zip
While generating DDL scripts for mapping files that declare id <generator class="org.hibernate.id.enhanced.SequenceStyleGenerator"> the following exception is thrown:
org.hibernate.MappingException: Dialect does not support pooled sequences
at org.hibernate.dialect.Dialect.getCreateSequenceString(Dialect.java:701)
at org.hibernate.dialect.Dialect.getCreateSequenceStrings(Dialect.java:659)
at org.hibernate.id.enhanced.SequenceStructure.sqlCreateStrings(SequenceStructure.java:139)
at org.hibernate.id.enhanced.SequenceStyleGenerator.sqlCreateStrings(SequenceStyleGenerator.java:328)
at org.hibernate.cfg.Configuration.generateSchemaCreationScript(Configuration.java:945)
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:129)
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:91)
I suspect the cause is in
org.hibernate.dialect.Dialect#getCreateSequenceString(String sequenceName, int initialValue, int incrementSize)
if ( supportsPooledSequences() ) {
return getCreateSequenceString( sequenceName ) + " start with " + initialValue + " increment by " + incrementSize;
}
throw new MappingException( "Dialect does not support pooled sequences" );
This call requires not just that dialect supports sequences but that dialect supports pooled sequences.
But the algorithm that tries to determine whether the table should be used to emulate the sequence lets the dialects that supports sequences but not pooled sequences to slip through. It looks like the DB2 and SAPDB dialects fail in this category because of:
org.hibernate.id.enhanced.SequenceStyleGenerator#configure(Type type, Properties params, Dialect dialect)
...
if ( dialect.supportsSequences() && !forceTableUse ) {
if ( OptimizerFactory.POOL.equals( optimizationStrategy ) && !dialect.supportsPooledSequences() ) {
forceTableUse = true;
log.info(
"Forcing table use for sequence-style generator due to pooled optimizer selection where db does not support pooled sequences"
);
}
}
To workaround the problem I have created my generator that overrides SequenceStyleGenerator#configure, somethng like:
public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
if (dialect.supportsSequences() && !dialect.supportsPooledSequences()) {
params.setProperty(FORCE_TBL_PARAM, "true");
}
super.configure(type, params, dialect);
Attached is a zip file with a small maven project with unit-test that replicates the problem. It generates DDL for different databases: Hipersonic, Derby, Oracle, MySql, PostgreSQL, MSSQL, DB2, and SAPDB. The data-model contains 2 tables Person and Event in many-to-many relation.
--
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
15 years, 7 months
[Hibernate-JIRA] Created: (HHH-2881) PersistantBag.initializeFromCache can be intercepted by CollectionLoadContext.getLoadingCollection and so corrupt the collection
by Pavol Zibrita (JIRA)
PersistantBag.initializeFromCache can be intercepted by CollectionLoadContext.getLoadingCollection and so corrupt the collection
--------------------------------------------------------------------------------------------------------------------------------
Key: HHH-2881
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2881
Project: Hibernate3
Issue Type: Bug
Environment: Hibernate Entity Manager 3.3.1 GA, oracle,
Reporter: Pavol Zibrita
It can occur that while PersistenBag.initializeFromCache is called to populate the collection from cache, the collection is populated also from CollectionLoadContext.getLoadingCollection, and so, the collection is filled with more data than needed. As the initializeFromCache uses direct access to the property this.bag, it will continue loading the collection. Here is the stack trace of what happens:
PersistentBag.beforeInitialize(CollectionPersister, int) line: xx //here is the same collection reinitialized again, and loaded again
CollectionLoadContext.getLoadingCollection(CollectionPersister, Serializable) line: 127
EntityLoader(Loader).readCollectionElement(Object, Serializable, CollectionPersister, CollectionAliases, ResultSet, SessionImplementor) line: 1003
EntityLoader(Loader).readCollectionElements(Object[], ResultSet, SessionImplementor) line: 646
EntityLoader(Loader).getRowFromResultSet(ResultSet, SessionImplementor, QueryParameters, LockMode[], EntityKey, List, EntityKey[], boolean) line: 591
EntityLoader(Loader).doQuery(SessionImplementor, QueryParameters, boolean) line: 701
EntityLoader(Loader).doQueryAndInitializeNonLazyCollections(SessionImplementor, QueryParameters, boolean) line: 236
EntityLoader(Loader).loadEntity(SessionImplementor, Object, Type, Object, String, Serializable, EntityPersister) line: 1860
EntityLoader(AbstractEntityLoader).load(SessionImplementor, Object, Object, Serializable) line: 48
EntityLoader(AbstractEntityLoader).load(Serializable, Object, SessionImplementor) line: 42
SingleTableEntityPersister(AbstractEntityPersister).load(Serializable, Object, LockMode, SessionImplementor) line: 3044
DefaultLoadEventListener.loadFromDatasource(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 395
DefaultLoadEventListener.doLoad(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 375
DefaultLoadEventListener.load(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 139
DefaultLoadEventListener.proxyOrLoad(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 195
DefaultLoadEventListener.onLoad(LoadEvent, LoadEventListener$LoadType) line: 103
SessionImpl.fireLoad(LoadEvent, LoadEventListener$LoadType) line: 878
SessionImpl.internalLoad(String, Serializable, boolean, boolean) line: 846
ManyToOneType(EntityType).resolveIdentifier(Serializable, SessionImplementor) line: 557
ManyToOneType.assemble(Serializable, SessionImplementor, Object) line: 196
TypeFactory.assemble(Serializable[], Type[], SessionImplementor, Object) line: 420
CacheEntry.assemble(Serializable[], Object, Serializable, EntityPersister, Interceptor, EventSource) line: 96
CacheEntry.assemble(Object, Serializable, EntityPersister, Interceptor, EventSource) line: 82
DefaultLoadEventListener.assembleCacheEntry(CacheEntry, Serializable, EntityPersister, LoadEvent) line: 553
DefaultLoadEventListener.loadFromSecondLevelCache(LoadEvent, EntityPersister, LoadEventListener$LoadType) line: 508
DefaultLoadEventListener.doLoad(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 357
DefaultLoadEventListener.load(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 139
DefaultLoadEventListener.proxyOrLoad(LoadEvent, EntityPersister, EntityKey, LoadEventListener$LoadType) line: 195
DefaultLoadEventListener.onLoad(LoadEvent, LoadEventListener$LoadType) line: 103
SessionImpl.fireLoad(LoadEvent, LoadEventListener$LoadType) line: 878
SessionImpl.internalLoad(String, Serializable, boolean, boolean) line: 846
ManyToOneType(EntityType).resolveIdentifier(Serializable, SessionImplementor) line: 557
ManyToOneType.assemble(Serializable, SessionImplementor, Object) line: 196
PersistentBag.initializeFromCache(CollectionPersister, Serializable, Object) line: xxx //NOW HERE IS THE Bag initializing from cache, it fails, see top of the stack!!
CollectionCacheEntry.assemble(PersistentCollection, CollectionPersister, Object) line: 35
DefaultInitializeCollectionEventListener.initializeCollectionFromCache(Serializable, CollectionPersister, PersistentCollection, SessionImplementor) line: 130
DefaultInitializeCollectionEventListener.onInitializeCollection(InitializeCollectionEvent) line: 48
SessionImpl.initializeCollection(PersistentCollection, boolean) line: 1716
PersistentBag(AbstractPersistentCollection).forceInitialization() line: 454
StatefulPersistenceContext.initializeNonLazyCollections() line: 794
QueryLoader(Loader).doQueryAndInitializeNonLazyCollections(SessionImplementor, QueryParameters, boolean) line: 241
QueryLoader(Loader).doList(SessionImplementor, QueryParameters) line: 2220
QueryLoader(Loader).listIgnoreQueryCache(SessionImplementor, QueryParameters) line: 2104
QueryLoader(Loader).list(SessionImplementor, QueryParameters, Set, Type[]) line: 2099
QueryLoader.list(SessionImplementor, QueryParameters) line: 378
QueryTranslatorImpl.list(SessionImplementor, QueryParameters) line: 338
HQLQueryPlan.performList(QueryParameters, SessionImplementor) line: 172
SessionImpl.list(String, QueryParameters) line: 1121
QueryImpl.list() line: 79
QueryImpl.getResultList() line: 66
//some stack before, uninportant
Small fix to the PersistantBag has resolved this issue, however I cannot tell if it is correct by some hibernate principles:
public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
throws HibernateException {
Serializable[] array = (Serializable[]) disassembled;
int size = array.length;
List<Object> elements = new ArrayList<Object>(size);
for ( int i = 0; i < size; i++ ) {
Object element = persister.getElementType().assemble( array[i], getSession(), owner );
if ( element!=null ) {
elements.add( element );
}
}
beforeInitialize( persister, size );
for ( Object element : elements ) {
this.bag.add( element );
}
}
Difference is, before the this.bag.add(element) was called in first cycle, where the line of getting the element could cause reinitializing the collection and filling it up. There are various possibilities how to fix the problem, but I don't know if the fix is at the right place!
--
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
15 years, 7 months
[Hibernate-JIRA] Created: (HHH-3046) Merge fails on complicated data structure because of cycle references
by Pavol Zibrita (JIRA)
Merge fails on complicated data structure because of cycle references
---------------------------------------------------------------------
Key: HHH-3046
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3046
Project: Hibernate3
Issue Type: Bug
Affects Versions: 3.2.4
Environment: Hibernate-3.2.4.ga, db-platform any (h2 & oracle tested)
Reporter: Pavol Zibrita
On complicated object structure, hibernate was unable to merge it correctly because of attaching ID's to the new objects in the tree of the persistent entity. Hibernate cannot cope with cyclic references in this case and it fails with:
javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: org.hibernate.bugtests.data.Transport.pickupNode
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:630)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:237)
at org.hibernate.bugtests.merge.MergeBug.mergeData(MergeBug.java:131)
at org.hibernate.bugtests.merge.MergeBug.testBug(MergeBug.java:149)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: org.hibernate.bugtests.data.Transport.pickupNode
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:290)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.ejb.event.EJB3MergeEventListener.saveWithGeneratedId(EJB3MergeEventListener.java:43)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:186)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:456)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:194)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:456)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:194)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:431)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:178)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:407)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:152)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:126)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:228)
... 20 more
However the value is set correctly.
--
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
15 years, 7 months
[Hibernate-JIRA] Created: (HHH-3810) Transient entities can be inserted twice on merge
by Gail Badner (JIRA)
Transient entities can be inserted twice on merge
-------------------------------------------------
Key: HHH-3810
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3810
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.3.1, 3.3.0.GA, 3.2.6
Reporter: Gail Badner
Assignee: Gail Badner
Fix For: 3.2.x, 3.3.x, 3.5
A transient entity being merged can be inserted twice if there is a cascade back to that same entity before it has been saved.
This bug was introduced by the fix for HHH-3229.
This can be illustrated by the following mapping (adapted from the test case at HHH-3046):
Route -- (1 : N) -- Node -- (N : 1) -- Tour
There are 3 objects:
route (persistent)
pickupNode (transient)
tour (transient)
Collections are sets.
node.route has cascade="none".
All other associations are cascade="merge,refresh"
route.nodes { pickupNode }
tour.nodes = { pickupNode }
pickupNode.route = route
pickupNode.tour = tour
The following shows the execution path that results in pickupNode being saved twice.
MERGE EVENT route (persistent)
MERGE EVENT pickupNode (transient)
|
| A) CASCADE_BEFORE_SAVE pickupNode
|
| MERGE EVENT tour (transient)
| |
| | A) CASCADE_BEFORE_SAVE tour (nothing to do)
| |
| | B) SAVE tour
| |
| | C) CASCADE_AFTER_SAVE tour
| |
| | MERGE EVENT pickupNode (still transient)
| | | (BUG: embedded merge event for same transient entity!!!)
| | |
| | | A) CASCADE_BEFORE_SAVE pickupNode
| | |
| | | MERGE EVENT tour (skip because it is already merged)
| | |
| | | B) SAVE pickupNode
| | | (BUG: saved in embedded merge event!!!)
| | |
| | | C) CASCADE_AFTER_SAVE pickupNode
| | |
|
| B) SAVE pickupNode
| (BUG: saved again in original merge event!!!)
|
| C) CASCADE_AFTER_SAVE pickupNode (nothing to do)
Prior to applying the fix for HHH-3229, the execution path was:
MERGE EVENT route (persistent)
MERGE EVENT pickupNode (transient)
|
| A) CASCADE_BEFORE_SAVE pickupNode
|
| MERGE EVENT tour (transient)
| |
| | A) CASCADE_BEFORE_SAVE tour (nothing to do)
| |
| | B) SAVE tour
| |
| | C) CASCADE_AFTER_SAVE tour
| |
| | MERGE EVENT pickupNode (still transient; skip because it is already being merged)
|
| B) SAVE pickupNode
|
| C) CASCADE_AFTER_SAVE pickupNode (nothing to do)
--
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
15 years, 7 months
[Hibernate-JIRA] Created: (EJB-419) EntityManager.persist validation: Inconsistent with other JPA Implemetations
by Francisco Peredo (JIRA)
EntityManager.persist validation: Inconsistent with other JPA Implemetations
------------------------------------------------------------------------------
Key: EJB-419
URL: http://opensource.atlassian.com/projects/hibernate/browse/EJB-419
Project: Hibernate Entity Manager
Issue Type: Bug
Affects Versions: 3.3.2.GA
Reporter: Francisco Peredo
With the following JPA @Entity:
@Entity
public class Customer {
private Long id;
private String name;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And then the following test
@Test
public void persistCustomerInTransaction() throws Exception {
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Customer customer = new Customer();
em.persist(customer);em.getTransaction().commit();
em.close();
}
Where does/should it crash?:
1. At the line em.persist(customer); because the name is configured as nullable=false, and we are trying to persist the Customer instance with a null value in the name property
2. em.getTransaction().commit(); because the name is configured as nullable=false, and we are trying to commit the transaction with a null value in the name property
Turns out... that the answer depends on the JPA provider you are using! If using Hibernate, it crashes at em.persist, but if using EclipseLink, it crashes at em.getTransaction().commit.
I think Hibernate it should validate this kind of things at em.getTransaction().commit() and not at em.persist.
--
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
15 years, 7 months
[Hibernate-JIRA] Created: (HHH-3532) schema update task should look for foreign key signature
by Dan Allen (JIRA)
schema update task should look for foreign key signature
--------------------------------------------------------
Key: HHH-3532
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3532
Project: Hibernate Core
Issue Type: Improvement
Components: metamodel
Affects Versions: 3.3.1
Reporter: Dan Allen
Priority: Minor
When the schema update task runs, it attempts to locate a foreign key in the database that matches the name provided in the Hibernate mapping information for that particular association. (The name of the foreign key is specified either in the foreign-key attribute in a mapping file or the @ForeignKey annotation). That much works fine. It's when a foreign key name is not provided, common in the case when standard JPA mappings are used, that problems arise.
When a foreign key name is not provided, Hibernate generates a key name as follows:
"FK" + hash code of referenced entity name + hash codes of columns
The chances of an existing foreign key in the database using this generated name is slim to none (every DBA has their own conventions that they follow). Thus, as soon as the scheme update task hits a database under these conditions, duplicate foreign key definitions appear all over the place.
If a foreign key name is not provided in the mapping, Hibernate should be looking instead to see if the signature of the foreign key matches that which is required to fulfill the mapping. In fact, I would even argue that the name is irrelevant and should only be used when actually *creating* the foreign key.
Here is the existing logic in the generateSchemaUpdateScript in Configuration:
ForeignKey fk = (ForeignKey) subIter.next();
boolean create = tableInfo == null || tableInfo.getForeignKeyMetadata( fk.getName() ) == null;
It should be like this instead:
ForeignKey fk = (ForeignKey) subIter.next();
boolean create = tableInfo == null || tableInfo.getForeignKeyMetadata( fk ) == null;
getForeignKeyMetadata should retrieve based on the fk signature rather than the fk name.
--
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
15 years, 7 months