Reputation: 3244
The given schema is not real; it is an example. This effort is useful for ORM mapping POJOs to legacy database schemas that cannot change.
Two tables, Person and Car:
Database Tables
------------------------- ------------------------- | Person | | Car | |-------------------------| |------------------------- | <PK> first_name: String | | owner_last_name: String | | <PK> last_name: String | ------------------------- -------------------------
Java Classes
class Person {
@Id
@Column(name="first_name")
String firstName;
@Id
@Column(name="last_name")
String lastName;
}
class Car {
@JoinColumn(name="owner_last_name", referencedColumnName="last_name")
@OneToOne(optional = true)
Person owner;
}
With the given example JPA annotations, the Hibernate error is:
org.hibernate.AnnotationException: referencedColumnNames(last_name) of com.example.Car.owner referencing com.example.Person not mapped to a single property
I would like to have the correct Person object when retrieving the Car object. Again, the schema cannot change.
Upvotes: 0
Views: 1478
Reputation: 106
There are several options for mapping a composite identifier which are listed in the hibernate documentation here:
http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch05.html#mapping-declaration-id
The hibernate documentation includes a warning against using the IdClass annotation.
Warning This approach is inherited from the EJB 2 days and we recommend against its use. But, after all it's your application and Hibernate supports it.
@Embeddable
class PersonId {
String firstName;
String lastName;
}
@Entity
@IdClass(PersonId.class)
class Person {
@Id
String firstName;
@Id
String lastName;
}
That being said, there are a few problems with your model. How can Car's owner relationship be one-to-one if in fact the last name in Person is not unique? It seems to me that Car's owner relationship must be one-to-many. Stated differently, if Person's last name is truly unique, then it should be used as the sole primary key thus simplifying the model.
@Entity
class Car {
@JoinColumn(name="owner_last_name", referencedColumnName="last_name")
@OneToMany
Set<Person> owners;
}
Perhaps it would be simpler to just create the entities without the relationships, and use a (criteria or hql) query to find the related objects.
Find all Persons who could possibly be owners of this car:
"select Person person, Car car where person.lastName = car.lastName and car.id=?"
Upvotes: 0
Reputation: 2819
You can use @Embeddeble
and @EmbeddedId
to create a composite key and map it with your Entity. For example:
@Embeddable
public class PersonCompositeID {
@Column(name="first_name")
String firstName;
@Column(name="last_name")
String lastName;
//getter, setter methods
}
@Entity
@Table(name = "Person")
public class Person {
@EmbeddedId
private PersonCompositeID personCompositeID;
/*setter getter methods */
}
hope this will solve your problem
Upvotes: 0