简体   繁体   English

Spring 和 JPA 2.0 - 与额外列的多对多关系中的复合键

[英]Spring and JPA 2.0 - Composite key in many to many relationship with extra column

I have two entities Foo and Bar in many-to-many relationship.我有两个实体 Foo 和 Bar 处于多对多关系中。 The joining entity is FooBar , and since this entity has another property (its own id), I used @ManyToOne on the owner side ( FooBar ) and @OneToMany in dependent entities ( Foo and Bar ).加入实体是FooBar ,由于该实体有另一个属性(它自己的 id),我在所有者端( FooBar )使用@ManyToOne ,在依赖实体( FooBar )中使用@OneToMany How to create a FooBarRepository extending CrudRepository without the explicit composite key field inside FooBar ?如何创建一个FooBarRepository扩展CrudRepository而没有FooBar内的显式复合键字段? Ideally, I don't want to change the members of my FooBar class.理想情况下,我不想更改FooBar class 的成员。

I tried to use @IdClass , but I don't want to have fields fooId and barId inside FooBar and I am getting this exception:我尝试使用@IdClass ,但我不想在FooBar中有字段fooIdbarId ,我得到了这个异常:

Caused by: org.hibernate.AnnotationException: Property of @IdClass not found in entity com.nano.testers.test.FooBar: barId

I also tried to follow the documentation of IdClass and reference columns by name explicitly, but I failed (maybe the solution lies somewhere here?)我还尝试按照名称明确遵循IdClass和引用列的文档,但我失败了(也许解决方案就在这里?)

The names of the fields or properties in the primary key class and the primary key fields or properties of the entity must correspond and their types must be the same.主键 class 中的字段或属性名称与实体的主键字段或属性名称必须对应且类型必须相同。

I tried to change the names of fields inside Foo and Bar to just id , so that they would be referenced as foo_id and bar_id in the joining table, but the exception was the same.我试图将FooBar中的字段名称更改为id ,以便它们在连接表中被引用为foo_idbar_id ,但例外是相同的。

I don't want to use @EmbeddedId , if that means I need to have a field of FooBarPk type inside the FooBar class.我不想使用@EmbeddedId ,如果这意味着我需要在FooBar class 中有一个FooBarPk类型的字段。

@Entity
public class Foo {
    @Id
    private Long fooId;

    @OneToMany(mappedBy = "foo", cascade = CascadeType.ALL)
    private Set<FooBar> foobars;
}
@Entity
public class Bar {
    @Id
    private Long barId;

    @OneToMany(mappedBy = "bar", cascade = CascadeType.ALL)
    private Set<FooBar> foobars;
}
@Entity
//@IdClass(FooBarPk.class)
public class FooBar implements Serializable {
    @Id
    private Long fooBarId;

    @Id
    @ManyToOne
    @JoinColumn
    private Foo foo;

    @Id
    @ManyToOne
    @JoinColumn
    private Bar bar;

}
public class FooBarPk implements Serializable {
    private Long fooId;
    private Long barId;
    private Long fooBarId;
}
public interface FooBarRepository extends CrudRepository<FooBar, FooBarPk> {
}

It looks like the names of the fields in the composite key class have to be the same as names of the referenced entities.看起来复合键 class 中的字段名称必须与引用实体的名称相同。 I think these names don't follow the clean code principles, but I will have to live with this solution for now.我认为这些名称不遵循干净的代码原则,但我现在必须接受这个解决方案。

public class FooBarPk implements Serializable {
    private Long foo;
    private Long bar;
    private Long fooBarId;
}

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

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