ManyToOne to a composite primary key
burnayev Feb 16, 2006 9:59 AMI've got what I think is a straightforward many-to-one to a composite primary key, which doesn't work as written. Here we go:
User entity reads like this:
@Entity
@Table(name = "CTVUSERS")
@IdClass(UserPK.class)
@SequenceGenerator(name = "UserSeq", sequenceName = "SQ_USER")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "UserSeq")
@Column(name = "CTVUSERS_KEY")
private Long userKey;
@Id
@Column(name = "CTVUSERS_START_DATE")
private Date startDate;
@Id
@Column(name = "CTVUSERS_END_DATE")
private Date endDate;
...
}
The UserPK is defined like this:
public class UserPK implements Serializable {
private static final long serialVersionUID = -7720874756224520523L;
private Long userKey;
private Date startDate;
private Date endDate;
public UserPK() {
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof UserPK))
return false;
UserPK userPK = (UserPK) obj;
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
return userKey.equals(userPK.userKey) && formatter.format(startDate).equals(formatter.format(userPK.startDate))
&& formatter.format(endDate).equals(formatter.format(userPK.endDate));
}
@Override
public int hashCode() {
return userKey.hashCode() * startDate.hashCode() * endDate.hashCode();
}
}
UserDistrict entity goes as follows:
@Entity
@Table(name = "CLRUS2DI")
@SequenceGenerator(name = "DistrictUserSeq", sequenceName = "SQ_DISTRICT_USER")
public class DistrictUser {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "DistrictUserSeq")
@Column(name = "CLRUS2DI_KEY")
private Long id;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumns( { @JoinColumn(name = "CLRUS2DI_USERS_KEY", referencedColumnName="CTVUSERS_KEY"),
@JoinColumn(name = "CLRUS2DI_BEGIN_DATE", referencedColumnName="CTVUSERS_START_DATE"),
@JoinColumn(name = "CLRUS2DI_END_DATE", referencedColumnName="CTVUSERS_END_DATE") })
private User user;
...
}
When I deploy the above I get:
Caused by: org.hibernate.MappingException: Unable to find column with logical name: CTVUSERS_KEY in org.hibernate.mapping.Table(CTVUSERS) and its related supertables and secondary tables
at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:346)
at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:80)
at org.hibernate.cfg.FkSecondPass.doSecondPass(FkSecondPass.java:43)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:233)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:997)
at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:722)
at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:161)
at org.hibernate.ejb.Ejb3Configuration.createEntityManagerFactory(Ejb3Configuration.java:567)
at org.hibernate.ejb.Ejb3Configuration.createContainerEntityManagerFactory(Ejb3Configuration.java:245)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:108)
at org.jboss.ejb3.entity.PersistenceUnitDeployment.start(PersistenceUnitDeployment.java:260)
If I remove the many-to-one from DistrictUsers everything works fine.
If I remove referenceColumnName's from the many-to-one specification, the code is deployed fine but then I have the following exception in runtime:
Caused by: java.sql.SQLException: ORA-00904: "USER10_"."ENDDATE": invalid identifier
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:799)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1039)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:839)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1132)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3329)
at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeQuery(WrappedPreparedStatement.java:211)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:139)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1669)
at org.hibernate.loader.Loader.doQuery(Loader.java:662)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1785)
which is expected as the column names are different
Any clues?