JPA: Foreign key that is also a primary key mapping

前端 未结 4 545
Happy的楠姐
Happy的楠姐 2020-12-09 10:05

I have been trying to solve this for whole day but no luck! Also i tried to read most of the tutorials on the net but as you all know they all are full of useless examples t

相关标签:
4条回答
  • 2020-12-09 10:18

    You can map your classes for example with Netbeans. It will generate annotations. The problem could be your dao layer. You have to persist objects in correct way. For example can't save travelExtra without Vehicle. Also be aware of owning side.

    0 讨论(0)
  • 2020-12-09 10:23

    The Java Persistence wikibook has a section called Primary Keys through OneToOne and ManyToOne Relationships which seems to indicate that what you want is possible.

    If I'm reading it right, for your case, it would look something like:

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

    Note that one of your entities will need to make sure it has the same id as the other, which is accomplished in the example by the TravelExtras constructor requiring the Vehicle it is bound to.

    0 讨论(0)
  • 2020-12-09 10:29

    I know this is very old qs, but for completeness of your case you can just have (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.
    }
    

    should share same pk/fk for VehicleExtra table

    0 讨论(0)
  • 2020-12-09 10:41

    Why don't you use an @Embedded object? When using an embedded object, you get the logical separation you desire in your code and keep your database compliant with Entity-Relational Normalization rules.

    It's weird to think on a One-to-One relationship, because even though JPA/Hibernate allows it, all data should be stored in the same table, making you model simpler, while also simplifying queries and increasing database performance by removing the need for a Join operation.

    When using Embedded objects you don't have to worry about mapping IDs and bizarre relations, since your ORM is capable of understanding that your just making a code separation, instead of demanding an actual relation of One-to-One between tables.

    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...
    }
    
    0 讨论(0)
提交回复
热议问题