Hello,
I have the following table structure:
Code:
CREATE TABLE first_entity (
first_entity_id NUMBER PRIMARY KEY
);
CREATE TABLE second_entity (
second_entity_id NUMBER PRIMARY KEY
);
CREATE TABLE comp_test (
first_entity_id NUMBER,
second_entity_id NUMBER,
PRIMARY KEY ( first_entity_id, second_entity_id )
);
So I have two "main" tables (first_entity and second_entity). Their keys combine to make a third table whose primary key is composed of these keys.
I've mapped the comp_test table with a composite primary key, like so:
Code:
@Entity
@Table( name="comp_test" )
@IdClass( CompTestPk.class )
public class CompTest implements Serializable
{
@Id
@ManyToOne
@JoinColumn( name="first_entity_id", nullable=false )
private FirstEntity firstEntity;
@Id
@ManyToOne
@JoinColumn( name="second_entity_id", nullable=false )
private SecondEntity secondEntity;
/* accessors */
}
I've also written a main method, just for the heck of it:
Code:
@SuppressWarnings( "unchecked" )
public static void main( String[] args )
{
try
{
AnnotationConfiguration configuration = new AnnotationConfiguration();
configuration.addAnnotatedClass( CompTest.class );
configuration.addAnnotatedClass( FirstEntity.class );
configuration.addAnnotatedClass( SecondEntity.class );
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
List<CompTest> items = session.createQuery( "from CompTest" ).list();
for ( CompTest t : items )
{
System.out.println( "(" + t.getFirstEntity().getId() + ", "
+ t.getSecondEntity().getId()+ ")" );
}
}
catch ( Throwable t )
{
t.printStackTrace();
}
}
My primary key class is as follows:
Code:
@Embeddable
class CompTestPk implements Serializable
{
public static final long serialVersionUID = 1;
private FirstEntity firstEntity;
private SecondEntity secondEntity;
/* Accessors, equals and hashCode */
}
Here are the first two entities. I don't get the problem until I add the @OneToMany association marked below in the FirstEntity class:
Code:
@Entity
@Table( name="first_entity" )
class FirstEntity implements Serializable
{
public static final long serialVersionUID = 1;
@Id
@Column( name="first_entity_id" )
private Long id;
/* PROBLEM when adding this property mapping. */
@OneToMany( mappedBy="firstEntity" )
@MapKey( name="secondEntity.id" )
private Map<Long, CompTest> tests = new TreeMap<Long, CompTest>();
/* Accessors */
}
@Entity
@Table( name="second_entity" )
class SecondEntity implements Serializable
{
public static final long serialVersionUID = 1;
@Id
@Column( name="second_entity_id" )
private Long id;
/* Accessors */
}
When I run the above code, I get the following error in the console:
Code:
10-Jul-2006 3:32:20 PM org.hibernate.cfg.annotations.CollectionBinder bindOneToManySecondPass
INFO: Mapping collection: test.db.FirstEntity.tests -> comp_test
org.hibernate.MappingException: property not found: firstEntity on entity test.db.CompTest
at org.hibernate.mapping.PersistentClass.getProperty(PersistentClass.java:377)
at org.hibernate.mapping.PersistentClass.getProperty(PersistentClass.java:382)
(...etc...)
Any ideas? Am I even doing the composite mapping correctly?
Thanks!
PS: This is an actual example I derived from my project's code. The only things I've removed from the stuff above are accessors, equals/hashCode and imports. The rest compiles, then executes, then terminates with an exception as shown. I stuck it all in the same file, CompTest.java (hence the missing 'public' keyword before all but the first class).
EDIT: I stepped through and noticed the property firstEntity isn't even listed in the property list during the configuration's second pass (boy there's a lot of stuff going on in that code). Is there any way to failfast when annotated properties aren't recorded in the class definition, so I could at least get a better idea what is going on? Lately I'm finding a lot of instances where annotated properties are simply not picked up at all (
http://forum.hibernate.org/viewtopic.php?p=2313830).