繁体   English   中英

JPA:外键也是主键映射

[英]JPA: Foreign key that is also a primary key mapping

我一整天都在试图解决这个问题,但没有运气! 此外,我尝试阅读网上的大部分教程,但众所周知,它们都充满了无用的示例,无法反映您在现实世界中的需求。

所以这是我的情况:

数据库:

表:车辆(vehicleId、品牌、型号、devYear、regNumber)<-- VehicleId 是主键

表:附加项(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 关系的部分,这似乎表明您想要的是可能的。

如果我没看错,对于你的情况,它看起来像:

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。

为什么不使用@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...
}

我知道这是非常古老的 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

例如,您可以使用 Netbeans 映射您的类。 它将生成注释。 问题可能出在你的 dao 层上。 您必须以正确的方式持久化对象。 例如,不能在没有 Vehicle 的情况下保存 travelExtra。 还要注意拥有方。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM