Hi
I want to specify a one-to-one mapping between a persisted subclass and another class. I can't get this to work. Maybe I'm doing something wrong, or maybe Hibernate can't handle this?
I'm basing this on:
http://assarconsulting.blogspot.com/200 ... y-key.htmlThe superclass:
Code:
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"username"})})
public class User implements UserDetails
{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "user_id")
private Long id;
...
The subclass:
Code:
@Entity
public class Performer extends User
{
@Column(length = 32)
private String phone;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "performer")
private Portfolio portfolio;
...
The extra class:
Code:
@Entity
@org.hibernate.annotations.GenericGenerator(name="performer-primarykey", strategy="foreign",
parameters={@org.hibernate.annotations.Parameter(name="property", value="performer") })
public class Portfolio implements Serializable
{
@Id
@GeneratedValue(generator = "performer-primarykey")
@Column(name = "portfolio_id")
private Long id;
@Column(length = 128)
private String posterFileName;
@OneToOne
@PrimaryKeyJoinColumn
private Performer performer;
...
When Hibernate attempts to build this, I get:
Code:
2455 [main] INFO org.springframework.context.support.GenericApplicationContext - Bean 'entityManagerFactory' of type [class org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2706 [main] INFO org.springframework.test.context.transaction.TransactionalTestExecutionListener - Began transaction (1): transaction manager [org.springframework.orm.jpa.JpaTransactionManager@42d134d0]; rollback [false]
2765 [main] WARN org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@76898587] to process 'after' execution for test: method [public void net.deepthought.next.domain.service.PerformerServiceTest.testPersist()], instance [net.deepthought.next.domain.service.PerformerServiceTest@3e9d9edd], exception [org.springframework.orm.hibernate3.HibernateSystemException: attempted to assign id from null one-to-one property [net.deepthought.next.domain.entity.Portfolio.performer]; nested exception is org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [net.deepthought.next.domain.entity.Portfolio.performer]]
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:476)
If the extra "Portfolio" class is excluded, the "Performer" subclass is persisted correctly, and shares the primary key with the "User" superclass.
I tried an alternative strategy, in which the "portfolio" class has its own auto-generated key. That worked fine, but the above solution would be be more elegant, I think.
Can it be made to work?
Thanks for your help.
Bruno.