I designed a component class called VersionInfo, and then include it as a member of classes I want versioned. When I try this, however, Hibernate is unable to handle it and dies with the exception included at the end of this message.
I then commented out VersionInfo and replaced it with a simple Long version member with a @Version annotation and, naturally, it worked. I think I'm missing something really obvious...
Has anyone deferred versioning to an embeddable component and gotten it to work? The documentation is a bit light, and all of the examples I've seen so far point to an immediate member version in the class you want versioned.
Thanks!
VersionInfo.java
Code:
@Embeddable
@AccessType("property")
public class VersionInfo
implements Serializable
{
private static final long serialVersionUID = 308500469244836364L;
private Long mVersion = 0L;
private Date mWhenCreated;
private Date mWhenLastModified;
public VersionInfo()
{
}
public VersionInfo( long version, Date whenCreated, Date whenLastModified )
{
setVersion( version );
setWhenCreated( whenCreated );
setWhenLastModified( whenLastModified );
}
/**
* @getter
* @return the version
*/
@Version
@Column(name="Version")
public Long getVersion()
{
return mVersion;
}
/**
* @setter
* @param version the version to set
*/
private void setVersion( Long version )
{
mVersion = version;
}
/**
* @getter
* @return the whenCreated
*/
@Column(name="WhenCreated")
@Temporal(TemporalType.TIMESTAMP)
public Date getWhenCreated()
{
return mWhenCreated;
}
/**
* @setter
* @param whenCreated the whenCreated to set
*/
private void setWhenCreated( Date whenCreated )
{
mWhenCreated = whenCreated;
}
/**
* @getter
* @return the whenLastModified
*/
@Column(name="WhenLastModified")
@Temporal(TemporalType.TIMESTAMP)
public Date getWhenLastModified()
{
return mWhenLastModified;
}
/**
* @setter
* @param whenLastModified the whenLastModified to set
*/
private void setWhenLastModified( Date whenLastModified )
{
mWhenLastModified = whenLastModified;
}
User.javaCode:
@Entity
@Table(name = "users")
@AccessType("property")
public class User
implements Serializable
{
private static final long serialVersionUID = -4424425974193496152L;
private int mId = 0;
private String mUsername;
private String mFirstName;
private String mLastName;
private Date mWhenLastLogin;
private VersionInfo mVersionInfo = new VersionInfo();
public User()
{
}
public User( int id )
{
setId( id );
}
/**
* @getter
* @return the firstName
*/
@Column(name = "FirstName", length = 100)
public String getFirstName()
{
return mFirstName;
}
/**
* @setter
* @param firstName
* the firstName to set
*/
public void setFirstName( String firstName )
{
mFirstName = firstName;
}
/**
* @getter
* @return the id
*/
@Id
@GeneratedValue
@Column(name = "UserID")
public int getId()
{
return mId;
}
/**
* @setter
* @param id
* the id to set
*/
private void setId( int id )
{
mId = id;
}
/**
* @getter
* @return the lastName
*/
@Column(name = "LastName", length = 100)
public String getLastName()
{
return mLastName;
}
/**
* @setter
* @param lastName
* the lastName to set
*/
public void setLastName( String lastName )
{
mLastName = lastName;
}
/**
* @getter
* @return the password
*/
@Column(name = "Password", nullable = false, length = 64)
public String getPassword()
{
return mPassword;
}
/**
* @setter
* @param password
* the password to set
*/
public void setPassword( String password )
{
mPassword = password;
}
/**
* @getter
* @return the username
*/
@Column(name = "Username", nullable = false, unique = true)
public String getUsername()
{
return mUsername;
}
/**
* @setter
* @param username
* the username to set
*/
public void setUsername( String username )
{
mUsername = username;
}
/**
* @getter
* @return the versionInfo
*/
@Embedded
public VersionInfo getVersionInfo()
{
return mVersionInfo;
}
/**
* @setter
* @param versionInfo
* the versionInfo to set
*/
public void setVersionInfo( VersionInfo versionInfo )
{
mVersionInfo = versionInfo;
}
}
Hibernate version: 3.2.1GA
Full stack trace of any exception that occurs:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao' defined in class path resource [dao.xml]: Cannot resolve reference to bean 'hibernateSessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateSessionFactory' defined in class path resource [dao.xml]: Invocation of init method failed; nested exception is java.lang.ArrayIndexOutOfBoundsException: -66
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateSessionFactory' defined in class path resource [dao.xml]: Invocation of init method failed; nested exception is java.lang.ArrayIndexOutOfBoundsException: -66
Caused by: java.lang.ArrayIndexOutOfBoundsException: -66
at org.hibernate.persister.entity.AbstractEntityPersister.checkVersion(AbstractEntityPersister.java:1859)
at org.hibernate.persister.entity.AbstractEntityPersister.generateUpdateString(AbstractEntityPersister.java:1815)
at org.hibernate.persister.entity.AbstractEntityPersister.generateUpdateString(AbstractEntityPersister.java:1781)
at org.hibernate.persister.entity.AbstractEntityPersister.postConstruct(AbstractEntityPersister.java:2934)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:409)
at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:55)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:226)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:805)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:745)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:134)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1202)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1172)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:428)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:261)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:109)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1100)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:862)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:424)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:251)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:156)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)
at org.springframework.test.AbstractSingleSpringContextTests.createApplicationContext(AbstractSingleSpringContextTests.java:199)
at org.springframework.test.AbstractSingleSpringContextTests.loadContextLocations(AbstractSingleSpringContextTests.java:179)
at org.springframework.test.AbstractSingleSpringContextTests.loadContext(AbstractSingleSpringContextTests.java:158)
at org.springframework.test.AbstractSpringContextTests.getContext(AbstractSpringContextTests.java:105)
at org.springframework.test.AbstractSingleSpringContextTests.setUp(AbstractSingleSpringContextTests.java:87)
at junit.framework.TestCase.runBare(TestCase.java:128)
at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:120)
at junit.framework.TestSuite.runTest(TestSuite.java:228)
at junit.framework.TestSuite.run(TestSuite.java:223)
at org.junit.internal.runners.OldTestClassRunner.run(OldTestClassRunner.java:35)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
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)
Name and version of the database you are using: MySQL 5.0.27
Debug level Hibernate log excerpt:2007-05-28 13:30:51,265 DEBUG - Processing annotations of com.cluehunters.common.domain.User.versionInfo
2007-05-28 13:30:51,265 DEBUG - Binding column versionInfo unique false
2007-05-28 13:30:51,265 DEBUG - Binding component with path: com.cluehunters.common.domain.User.versionInfo
2007-05-28 13:30:51,265 DEBUG - Processing com.cluehunters.common.domain.VersionInfo property annotation
2007-05-28 13:30:51,265 DEBUG - Processing annotations of com.cluehunters.common.domain.VersionInfo.version
2007-05-28 13:30:51,265 DEBUG - Binding column Version unique false
2007-05-28 13:30:51,265 DEBUG - version is a version property
2007-05-28 13:30:51,265 DEBUG - binding property version with lazy=false
2007-05-28 13:30:51,265 DEBUG - building SimpleValue for version
2007-05-28 13:30:51,265 DEBUG - Building property version
2007-05-28 13:30:51,265 DEBUG - Version name: version, unsavedValue: undefined
2007-05-28 13:30:51,265 DEBUG - Processing annotations of com.cluehunters.common.domain.VersionInfo.whenCreated
2007-05-28 13:30:51,265 DEBUG - Binding column WhenCreated unique false
2007-05-28 13:30:51,265 DEBUG - binding property whenCreated with lazy=false
2007-05-28 13:30:51,265 DEBUG - building SimpleValue for whenCreated
2007-05-28 13:30:51,265 DEBUG - Building property whenCreated
2007-05-28 13:30:51,265 DEBUG - Processing annotations of com.cluehunters.common.domain.VersionInfo.whenLastModified
2007-05-28 13:30:51,265 DEBUG - Binding column WhenLastModified unique false
2007-05-28 13:30:51,265 DEBUG - binding property whenLastModified with lazy=false
2007-05-28 13:30:51,265 DEBUG - building SimpleValue for whenLastModified
2007-05-28 13:30:51,265 DEBUG - Building property whenLastModified
2007-05-28 13:30:51,265 DEBUG - Building property versionInfo
Code:
[b][/b]