-
1. Re: Saving new collection and its first element with same se
dmeyer2 Jan 28, 2009 1:28 PM (in response to dmeyer2)The title of the post should be: Saving new collection and its first element with same session.save() yields exception when using JTA transaction manager
-
2. Re: Saving new collection and its first element with same se
adamw Jan 29, 2009 3:58 AM (in response to dmeyer2)Hello,
what's the exact exception? And what's the mapping of the Greeting classes?
--
Adam -
3. Re: Saving new collection and its first element with same se
dmeyer2 Jan 29, 2009 11:27 AM (in response to dmeyer2)what's the exact exception?
The exception is:
org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of com.ontsys.db.GreetingPO.id
The exception is coming from a reflective call to method.invoke() in org.hibernate.property.BasicPropertyAccessor.BasicSetter.set():
method.invoke( target, new Object[] { value } );
During the invocation that triggers the exception, target and value hold the following data:- target=(java.util.HashMap<K,V>) {VER_REV_TYPE=ADD, originalId={nullid=419, VER_REV=com.ontsys.db.RevisionEntityPO@ac3e4, greetingSet_id=418}}
- value=(java.lang.Long) 421(RevisionEntityPO is the @RevisionEntity table, configured for Oracle.)
BasicPropertyAccessor.BasicSetter.set() catches the IllegalArgumentException, logs these messages:
IllegalArgumentException in class: com.ontsys.db.GreetingPO, setter method of property: id
expected type: java.lang.Long, actual value: java.lang.Long
...and then throws the PropertyAccessException.And what's the mapping of the Greeting classes?
Here's GreetingPO.java:package com.ontsys.db; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import org.jboss.envers.Versioned; @Entity @Table @Versioned public class GreetingPO { private Long id; private String theGreeting; private GreetingSetPO greetingSet; @Id @GeneratedValue public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Column public String getGreeting() { return theGreeting; } public void setGreeting(String greeting) { this.theGreeting = greeting; } @ManyToOne @JoinColumn public GreetingSetPO getGreetingSet() { return greetingSet; } public void setGreetingSet(GreetingSetPO greetingSet) { this.greetingSet = greetingSet; } }
GreetingSetPO.java:package com.ontsys.db; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import org.jboss.envers.Versioned; @Entity @Table @Versioned public class GreetingSetPO { private Long id; private String name; private Set<GreetingPO> members; @Id @GeneratedValue public Long getId() { return id; } public void setId(Long id) { this.id = id; } @OneToMany(cascade = CascadeType.ALL, mappedBy = "greetingSet") public Set<GreetingPO> getMembers() { return members; } public void setMembers(Set<GreetingPO> members) { this.members = members; } @Column public String getName() { return name; } public void setName(String name) { this.name = name; } }
RevisionEntityPO.java:package com.ontsys.db; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import org.jboss.envers.RevisionEntity; import org.jboss.envers.RevisionNumber; import org.jboss.envers.RevisionTimestamp; @Entity @RevisionEntity @Table(name = "REV_ENT") public class RevisionEntityPO { private Integer id; private Long timestamp; @Id @GeneratedValue @RevisionNumber @Column(name = "ID") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @RevisionTimestamp @Column(name = "TMSTMP") public Long getTimestamp() { return timestamp; } public void setTimestamp(Long timestamp) { this.timestamp = timestamp; } }
I'll also include here the Hibernate config, in case it helps:<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="myDataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop> <prop key="hibernate.hbm2ddl.auto">validate</prop> <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.BTMTransactionManagerLookup</prop> <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop> <!--these fields need renamed from their default values. The default names start with an underscore, which is illegal in oracle --> <prop key="org.jboss.envers.revisionTypeFieldName">VER_REV_TYPE</prop> <prop key="org.jboss.envers.revisionFieldName">VER_REV</prop> <prop key="org.jboss.envers.versionsTableSuffix">_V</prop> <!-- The following are the default values for these settings. We just wanted to be explicit about it --> <prop key="org.jboss.envers.versionsTablePrefix"></prop> <prop key="org.jboss.envers.revisionOnCollectionChange">true</prop> <prop key="org.jboss.envers.warnOnUnsupportedTypes">false</prop> <prop key="org.jboss.envers.unversionedOptimisticLockingField">false</prop> </props> </property> <property name="eventListeners"> <map> <entry key="post-insert"> <ref local="versionsEventListener" /> </entry> <entry key="post-update"> <ref local="versionsEventListener" /> </entry> <entry key="post-delete"> <ref local="versionsEventListener" /> </entry> <entry key="pre-collection-update"> <ref local="versionsEventListener" /> </entry> <entry key="pre-collection-remove"> <ref local="versionsEventListener" /> </entry> <entry key="post-collection-recreate"> <ref local="versionsEventListener" /> </entry> </map> </property> <property name="annotatedClasses"> <list> <value>com.ontsys.db.RevisionEntityPO</value> <value>com.ontsys.db.GreetingPO</value> <value>com.ontsys.db.GreetingSetPO</value> </list> </property> </bean>
And finally, again just in case it helps, here's the call stack at the method.invoke() that throws the PropertyAccessException:
Thread [main] (Suspended (breakpoint at line 66 in org.hibernate.property.BasicPropertyAccessor$BasicSetter))
org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(Object, Object, SessionFactoryImplementor) line: 66
org.hibernate.tuple.entity.PojoEntityTuplizer(AbstractEntityTuplizer).setIdentifier(Object, Serializable) line: 234
org.hibernate.persister.entity.SingleTableEntityPersister(AbstractEntityPersister).setIdentifier(Object, Serializable, EntityMode) line: 3624
org.hibernate.event.def.DefaultSaveEventListener(AbstractSaveEventListener).performSave(Object, Serializable, EntityPersister, boolean, Object, EventSource, boolean) line: 194
org.hibernate.event.def.DefaultSaveEventListener(AbstractSaveEventListener).saveWithGeneratedId(Object, String, Object, EventSource, boolean) line: 144
org.hibernate.event.def.DefaultSaveEventListener(DefaultSaveOrUpdateEventListener).saveWithGeneratedOrRequestedId(SaveOrUpdateEvent) line: 210
org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(SaveOrUpdateEvent) line: 56
org.hibernate.event.def.DefaultSaveEventListener(DefaultSaveOrUpdateEventListener).entityIsTransient(SaveOrUpdateEvent) line: 195
org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(SaveOrUpdateEvent) line: 50
org.hibernate.event.def.DefaultSaveEventListener(DefaultSaveOrUpdateEventListener).onSaveOrUpdate(SaveOrUpdateEvent) line: 93
org.hibernate.impl.SessionImpl.fireSave(SaveOrUpdateEvent) line: 562
org.hibernate.impl.SessionImpl.save(String, Object) line: 550
org.jboss.envers.synchronization.work.PersistentCollectionChangeWorkUnit.perform(Session, Object) line: 67
org.jboss.envers.synchronization.VersionsSync.executeInSession(Session) line: 120
org.jboss.envers.synchronization.VersionsSync.beforeCompletion() line: 135
bitronix.tm.BitronixTransaction.fireBeforeCompletionEvent() line: 366
bitronix.tm.BitronixTransaction.commit() line: 142
bitronix.tm.BitronixTransactionManager.commit() line: 96
org.springframework.transaction.jta.JtaTransactionManager.doCommit(DefaultTransactionStatus) line: 1028
org.springframework.transaction.jta.JtaTransactionManager(AbstractPlatformTransactionManager).processCommit(DefaultTransactionStatus) line: 732
org.springframework.transaction.jta.JtaTransactionManager(AbstractPlatformTransactionManager).commit(TransactionStatus) line: 701
org.springframework.transaction.interceptor.TransactionInterceptor(TransactionAspectSupport).commitTransactionAfterReturning(TransactionAspectSupport$TransactionInfo) line: 321
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(MethodInvocation) line: 116
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation(ReflectiveMethodInvocation).proceed() line: 171
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(MethodInvocation) line: 89
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation(ReflectiveMethodInvocation).proceed() line: 171
org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 635
com.ontsys.db.GreetingSetDAO$$EnhancerByCGLIB$$cd993582.create(GreetingSetPO) line: not available
com.ontsys.db.EnversWithCollectionsTest.testComplexCreate() line: 112
sun.reflect.NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]
sun.reflect.NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
sun.reflect.DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
java.lang.reflect.Method.invoke(Object, Object...) line: 597
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall() line: 44
org.junit.runners.model.FrameworkMethod$1(ReflectiveCallable).run() line: 15
org.junit.runners.model.FrameworkMethod.invokeExplosively(Object, Object...) line: 41
org.junit.internal.runners.statements.InvokeMethod.evaluate() line: 20
org.junit.internal.runners.statements.RunBefores.evaluate() line: 28
org.junit.internal.runners.statements.RunAfters.evaluate() line: 31
org.junit.runners.BlockJUnit4ClassRunner.runChild(FrameworkMethod, RunNotifier) line: 73
org.junit.runners.BlockJUnit4ClassRunner.runChild(Object, RunNotifier) line: 46
org.junit.runners.BlockJUnit4ClassRunner(ParentRunner).runChildren(RunNotifier) line: 180
org.junit.runners.ParentRunner.access$000(ParentRunner, RunNotifier) line: 41
org.junit.runners.ParentRunner$1.evaluate() line: 173
org.junit.internal.runners.statements.RunBefores.evaluate() line: 28
org.junit.internal.runners.statements.RunAfters.evaluate() line: 31
org.junit.runners.BlockJUnit4ClassRunner(ParentRunner).run(RunNotifier) line: 220
org.eclipse.jdt.internal.junit4.runner.JUnit4TestMethodReference(JUnit4TestReference).run(TestExecution) line: 38
org.eclipse.jdt.internal.junit.runner.TestExecution.run(ITestReference[]) line: 38
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(String[], String, TestExecution) line: 460
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(TestExecution) line: 673
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run() line: 386
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(String[]) line: 196
-
4. Re: Saving new collection and its first element with same se
dmeyer2 Feb 2, 2009 11:52 AM (in response to dmeyer2)I wonder if my bidirectional one-to-many relationship is set up correctly in the annotated classes? Reading in preparation to post to a Hibernate forum made me realize that there are some Hibernate concepts I may need to understand more deeply.
I've written in more detail here: http://ourcraft.wordpress.com/2009/01/30/hibernate-one-to-many-foray/ -
5. Re: Saving new collection and its first element with same se
adamw Feb 3, 2009 1:36 PM (in response to dmeyer2)Hello,
I didn't have much time to read your posts in detail yet, but the mappings seem ok.
There is one very strange thing:
"expected type: java.lang.Long, actual value: java.lang.Long"
(in the exception)
This looks like a classloading problem. In most classloading scenarios I've seen, java.lang was in the base classloader, and not isolated - but maybe Spring is different here. Maybe sth with OSGi? Are you using it?
I never used Spring so I don't think I won't be of much help here. Maybe look in the FAQ:
https://www.jboss.org/community/docs/DOC-13216
--
Adam