JPA:外键,也是主键映射

2022-09-02 09:28:00

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

所以这是我的情况:

数据库:

表:车辆(车辆标识、品牌、型号、开发年份、注册编号)<-- 车辆标识是主要密钥

表:附加(vehicleId,allowSmoke,allowFood,allowDrinks,airCioner)< - vehicleId是PK和FK。

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

不幸的是,无论我尝试在databse中持久化对象时尝试了什么,我都会得到各种错误。

下面是一个插图:

        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( );

任何人都知道对于这种情况使用哪种注释?


答案 1

Java Persistence维基教科书有一个名为“通过OneToOne和ManyToOne Relations进行主键”的部分,这似乎表明你想要的是可能的。

如果我没看错的话,就你的情况来看,它看起来像这样:

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,这在示例中由 TravelExtras 构造函数完成,该构造函数要求绑定到 Vehicle。


答案 2

我知道这是非常古老的qs,但是为了你的案例的完整性,你可以拥有(jpa 2.0)

@Entity
@Data
public class Vehicle implements Serializable{
   @Id
   @GeneratedValue
   private long vehicleId;
   .. //other props
}

@Entity
@Data
public class VehicleExtras implements Serializable{
         @Id
         @OneToOne (cascade = CASCADE.ALL)
         @MapsId
         @JoinColumn(name ="vehicleId")
         private Vehicle vehicle;

         @Column  
         private boolean allowSmoke; 
         ..// other props.
}

应该为 VehicleExtra 表共享相同的 pk/fk


推荐