简体   繁体   中英

@OneToMany mapping with Composite Primary Key not working as expected

I'm trying to implement a OneToMany mapping with a composite primary key in my application. The entities involved in the application are as follows:

// Config data
@Data
@Entity
public class Config {

    @Id
    @GeneratedValue
    private int id;

    @OneToMany(mappedBy = "config", fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
    private Set<Mapping> mappings;
}

The class with Composite key is:

@Data
@Entity
public class Mapping {
    @EmbeddedId
    private MappingId mappingId;

    @ElementCollection
    private List<Integer> values;

    @ManyToOne
    @JoinColumn(name = "id", nullable = false, insertable = false, updatable = false)
    private Config config;
}

The composite key:

@Data
@Embeddable
public class MappingId implements Serializable {
    private int id;
    private String comment;
}

Now, I'm trying to save the following Config json data:

{
    "mappings": [
        {
            "mappingId": {
                "comment": "comment#1"
            },
            "values": [
                123,
                456
            ]
        }
    ]
}

The code is supposed to generate a value for id column automatically and assign it to both Config.id and Mapping.mappingId.id . But the values of these variables is not matching. After calling save method on config object, value of Config.id is set to 1 whereas Mapping.mappingId.id is set to 0 which is not correct. Can someone tell me what is going wrong here?

Thanks.

You're missing a @MapsId annotation on your Config config attribute.

The @MapsId annotation tells Hibernate that the primary key of the associated entity shall be used as the primary key or as a part of a composite primary key. If you use it with a composite primary key, you need to reference the attribute to which the primary key value of the associated entity shall be mapped.

This mapping should set the value of Config.id as Mapping.mappingId.id :

@Data
@Entity
public class Mapping {
    @EmbeddedId
    private MappingId mappingId;

    @ElementCollection
    private List<Integer> values;

    @ManyToOne
    @JoinColumn(name = "id", nullable = false, insertable = false, updatable = false)
    @MapsId("id")
    private Config config;
}

And here you can see a complete example of such a mapping.

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