简体   繁体   中英

Hibernate Composite Key Join

I'm trying to use Spring Data to perform joined queries but one of my tables has a Composite Key and I'm not sure how to map the entities.

Here is an analogy of the data model:

table: device
pk=model_id
pk=serial_id
...

table: device_settings
pk=device_settings_id
fk=model_id
fk=serial_id
...

Here is an analogy of the code, which doesn't compile due to a "mappedby" attribute that is isn't present.

@Entity
@Table(name = "device_settings")
public class DeviceSettings {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "device_settings_id")
    private Long id;

    // Pretty sure this is the problem
    @OneToMany(targetEntity = Device.class, mappedBy = "deviceKey", cascade = {CascadeType.MERGE}, fetch = FetchType.EAGER)
    @JoinColumns({
        @JoinColumn(name = "model_id", referencedColumnName = "model_id"),
        @JoinColumn(name = "serial_id", referencedColumnName = "serial_id")})
    private List<Device> devices;
}

@Entity
@Table(name = "device")
public class Device {
    @Id
        private DeviceKey deviceKey;
    }
    ...
}


@Embeddable
public class DeviceKey implements Serializable {
    private static final long serialVersionUID = -1943684511893963184L;

    @Column(name = "model_id")
    private Long modelId;

    @Column(name = "serial_id")
    private Short serialId;
}

Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn

To achieve your scenario you have to define @ManyToOne:

@ManyToOne(cascade = {CascadeType.MERGE}, fetch = FetchType.EAGER)
    @JoinColumns({
        @JoinColumn(name = "model_id", referencedColumnName = "model_id"),
        @JoinColumn(name = "serial_id", referencedColumnName = "serial_id")})
     private Device device;

This will end up model_id, serial_id, device_settings_id

or

Define @JoinColumn in Device Entity Entities:

DeviceSettings :

    @Entity
    @Table(name = "device_settings")
    public class DeviceSettings {

        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "device_settings_id")
        private Long id;


        @OneToMany( mappedBy = "deviceSettings", cascade = {CascadeType.MERGE}, fetch = FetchType.EAGER)
         private List<Device> devices;
}

Device Entity :

@Entity
@Table(name = "device")
public class Device {

        @EmbeddedId
        private DeviceKey deviceKey;

        @ManyToOne
        @JoinColumn(name="device_settings_id")
        private DeviceSettings deviceSettings;
       //getters and setters
}

Note : you can decide which is the owner of the relationship and put your mappings accorindly either One Device has many device settings or other way around.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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