Hibernate version:
Hibernate 3.3.0.GA
hibernate-entitymanager-3.3.1.GA
Hibernate annotation version shipped with hibernate-entitymanager-3.3.1.GA
Mapping documents:
I added following two classes in org.hibernate.test.annotations.cid package
Code:
package org.hibernate.test.annotations.cid;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Column;
import java.util.Date;
@Entity
@SecondaryTable(name = "TV_PROGRAM_IDCLASS", pkJoinColumns = {
@PrimaryKeyJoinColumn(name = "CHANNEL_ID"),
@PrimaryKeyJoinColumn(name = "PRESENTER_NAME")
})
@IdClass(TvMagazinPk.class)
public class TvProgramIdClass {
@Id
public Channel channel;
@Id
public Presenter presenter;
@Temporal(TemporalType.TIME)
Date time;
@Column(name = "TXT", table = "TV_PROGRAM_IDCLASS")
public String text;
}
Code:
package org.hibernate.test.annotations.cid;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.util.Date;
@Entity
@SecondaryTable(name = "TV_PROGRAM_EXT", pkJoinColumns = {
@PrimaryKeyJoinColumn(name = "CHANNEL_ID"),
@PrimaryKeyJoinColumn(name = "PRESENTER_NAME")
})
public class TvProgram {
@EmbeddedId
public TvMagazinPk id;
@Temporal(TemporalType.TIME)
Date time;
@Column(name = "TXT", table = "TV_PROGRAM_EXT")
public String text;
}
Code between sessionFactory.openSession() and session.close():Added two test cases to org.hibernate.test.annotations.cid.CompositeIdTest
Code:
public void testSecondaryTableWithCompositeId() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Channel channel = new Channel();
s.persist( channel );
Presenter pres = new Presenter();
pres.name = "Tim Russet";
s.persist( pres );
TvMagazinPk pk = new TvMagazinPk();
TvProgram program = new TvProgram();
program.time = new Date();
program.id = pk;
program.text = "Award Winning Programming";
//pk.name = "Trax";
pk.channel = channel;
pk.presenter = pres;
s.persist( program );
tx.commit();
s.clear();
tx = s.beginTransaction();
program = (TvProgram) s.createQuery( "from TvProgram pr" ) // where mag.id.name = :name")
//.setParameter( "name", "Trax" )
.uniqueResult();
assertNotNull( program.id );
assertNotNull( program.id.channel );
assertEquals( channel.id, program.id.channel.id );
assertNotNull( program.id.presenter );
assertNotNull( program.text );
assertEquals( pres.name, program.id.presenter.name );
s.delete( program );
s.delete( program.id.channel );
s.delete( program.id.presenter );
tx.commit();
s.close();
}
public void testSecondaryTableWithIdClass() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Channel channel = new Channel();
s.persist( channel );
Presenter pres = new Presenter();
pres.name = "Bob";
s.persist( pres );
TvProgramIdClass program = new TvProgramIdClass();
program.time = new Date();
program.channel = channel;
program.presenter = pres;
program.text = "Jump the shark programming";
//pk.name = "Trax";
s.persist( program );
tx.commit();
s.clear();
tx = s.beginTransaction();
program = (TvProgramIdClass) s.createQuery( "from TvProgramIdClass pr" ) // where mag.id.name = :name")
//.setParameter( "name", "Trax" )
.uniqueResult();
assertNotNull( program.channel );
assertEquals( channel.id, program.channel.id );
assertNotNull( program.presenter );
assertNotNull( program.text );
assertEquals( pres.name, program.presenter.name );
s.delete( program );
s.delete( program.channel );
s.delete( program.presenter );
tx.commit();
s.close();
}
Full stack trace of any exception that occurs: The test fails with following stack trace
Code:
java.util.NoSuchElementException
at java.util.AbstractList$Itr.next(AbstractList.java:427)
at org.hibernate.util.JoinedIterator.next(JoinedIterator.java:53)
at org.hibernate.cfg.Ejb3JoinColumn.buildJoinColumn(Ejb3JoinColumn.java:210)
at org.hibernate.cfg.annotations.EntityBinder.createPrimaryColumnsToSecondaryTable(EntityBinder.java:483)
at org.hibernate.cfg.annotations.EntityBinder.finalSecondaryTableBinding(EntityBinder.java:440)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:770)
at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:498)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:277)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1286)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:915)
at org.hibernate.test.annotations.TestCase.buildSessionFactory(TestCase.java:51)
Both of these test fail. The workaround is to use hbm.xml join instead of EJB3 annotation.