2013-12-23 33 views
0

给定的模式不是真实的;这是一个例子。这项工作对于将POJO映射到无法更改的传统数据库模式很有用。针对引用复合键列的列的休眠JPA映射,但没有外键关联

两个表,人与车:

  • 人有Person.lastName的firstName和lastName
  • 汽车引用在OneToOne自己的
  • 人与汽车是一个复合键,可空列在数据库模式中不相关;没有外键

数据库表

------------------------- ------------------------- 
| Person     | | Car      | 
|-------------------------| |------------------------- 
| <PK> first_name: String | | owner_last_name: String | 
| <PK> last_name: String | ------------------------- 
------------------------- 

Java类

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; 
} 

在给定的例子JPA注释,Hibernate的错误是:

org.hibernate.AnnotationException: referencedColumnNames(last_name) of com.example.Car.owner referencing com.example.Person not mapped to a single property 

我想在检索Car对象时拥有正确的Person对象。同样,模式不能改变。

回答

0

您可以使用@Embeddeble@EmbeddedId来创建组合键并将其与您的实体进行映射。例如:

@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 */ 
} 

希望这将解决您的问题

+0

阿希什,我最初使用这个模式,但决定,因为我的@Id例如工作相同,除去额外的层和更清晰阅读并理解。 – Matt

0

有映射这是Hibernate文档在这里列出的组合标识符几个选项:

http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch05.html#mapping-declaration-id

Hibernate文档包括使用IdClass注释的警告。

警告此方法从EJB 2天继承,我们推荐使用 。但毕竟它是你的应用程序,Hibernate支持它。

@Embeddable 
class PersonId { 
    String firstName; 
    String lastName; 
} 

@Entity 
@IdClass(PersonId.class)  
class Person { 
    @Id 
    String firstName; 

    @Id 
    String lastName; 
} 

话虽这么说,有你的模式中的一些问题。如果车上的姓氏不是唯一的,车主的关系如何能够一对一?在我看来,汽车的车主关系必须是一对多的关系。换句话说,如果Person的姓氏是真正独特的,那么它应该被用作唯一的主键,从而简化模型。

@Entity 
class Car { 
    @JoinColumn(name="owner_last_name", referencedColumnName="last_name") 
    @OneToMany 
    Set<Person> owners; 
} 

也许这将是简单的只需要创建一个没有实体的关系,并使用(标准或HQL)查询来查找相关的对象。

找到所有谁也可能会被这辆车的拥有人:

"select Person person, Car car where person.lastName = car.lastName and car.id=?" 
+0

我试图弄清楚模型不会改变。看起来Hibernate不支持关联这些不相关的实体。因此,使用查询可能是强制关联的唯一方法。 – Matt