JPA:外键也是主键映射

我一整天都试图解决这个问题,但没有运气! 此外,我试图阅读网络上的大多数教程,但众所周知,他们都充满了无用的例子,不能反映你在现实世界中的需求。

所以这是我的情况:

数据库:

表: 车辆 (vehicleId,品牌,型号,devYear,regNumber)< – vehicleId是PrimaryKey

table: extras (vehicleId,allowSmoke,allowFood,allowDrinks,airConditioner)< – vehicleId是PK和FK。

关键是,如果我有一个类Vehicle和一个映射到数据库的类TravelExtras ,我希望Vehicle类具有一个属性TravelExtras travelExtras和get和set方法。

不幸的是,无论我尝试在数据库中持久保存对象时我都会遇到各种错误。

这是一个例子:

EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "NaStopPU" ); EntityManager entitymanager = emfactory.createEntityManager( ); entitymanager.getTransaction( ).begin( ); TravelExtra travelExtra = new TravelExtra(); entitymanager.persist(travelExtra); Vehicle vehicle = new Vehicle(2L, "10152487958556242", "Mazda", "626", "334343", 2005, 4); vehicle.setTravelExtra(travelExtra); entitymanager.persist(vehicle); entitymanager.getTransaction().commit(); entitymanager.close( ); emfactory.close( ); 

任何人都知道这种一对一的案例使用什么样的注释?

Java Persistence wikibook有一个名为Primary Keys through OneToOne和ManyToOne Relationships的部分 ,似乎表明你想要的是可能的。

如果我正确地阅读它,对于你的情况,它看起来像:

 class Vehicle { @Id @Column(name = "EXTRAS_ID") private long extrasId; @OneToOne(mappedBy="vehicle", cascade=CascadeType.ALL) private TravelExtra extras; } class TravelExtras { @Id @Column(name = "VEHICLE_ID") private long vehicleId; @OneToOne @PrimaryKeyJoinColumn(name="VEHICLE_ID", referencedColumnName="EXTRAS_ID") private Vehicle vehicle; public TravelExtras(Vehicle vehicle) { this.vehicleId = vehicle.getId(); this.vehicle = vehicle; } } 

请注意,您的某个实体需要确保它具有与另一个实体相同的ID,这在示例中由需要其绑定的Vehicle的TravelExtras构造函数完成。

为什么不使用@Embedded对象? 使用嵌入式对象时,您可以在代码中获得所需的逻辑分离,并使数据库符合实体关系规范化规则。

考虑一对一关系是很奇怪的,因为即使JPA / Hibernate允许它,所有数据都应存储在同一个表中,使您的模型更简单,同时通过消除对查询的需求,简化查询并提高数据库性能加入操作。

使用嵌入式对象时,您不必担心映射ID和奇怪的关系,因为您的ORM能够理解您只是进行代码分离,而不是要求表之间实际的一对一关系。

 class Vehicle { @Id @Column(name = "ID") private long vehicleId; @Column(name = "BRAND") private String brand; @Column(name = "MODEL") private String model; @Column(name = "DEV_YEAR") private int devYear; @Column(name = "REG_NUMBER") private int regNumber; @Embedded private TravelExtra extras; // Constructor, getters and setters... } 

 @Embeddable class TravelExtras { @Column(name = "ALLOW_SMOKE") private boolean allowSmoke; @Column(name = "ALLOW_FOOD") private boolean allowFood; @Column(name = "ALLOW_DRINKS") private boolean allowDrinks; @Column(name = "AIR_CONDITIONER") private boolean airConditioner; // Default Constructor, getters and setters... } 

您可以使用Netbeans映射您的类。 它会生成注释。 问题可能是你的dao层。 你必须以正确的方式持久化对象。 例如,没有Vehicle就无法保存travelExtra。 也要注意拥有方。