我有两个具有@ManyToMany关系的实体。他们看起来像这样:
@Entity
@Table(name = "owner")
@Inheritance(strategy = InheritanceType.JOINED)
public class Owner implements Serializable {
@Column(name = "id", updatable = false, nullable = false)
private Integer id;
@Id
private String name;
@ManyToMany(fetch = FetchType.EAGER,
cascade = {CascadeType.PERSIST, CascadeType.MERGE}
)
@JoinTable(name = "owner_dog",
joinColumns = @JoinColumn(name = "owner_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "dog_id", referencedColumnName = "id")
)
private Set<Dog> dogs = new HashSet<>();
}
@Entity
@Table(name = "dog")
public class Dog implements Serializable {
@Id
@Column(name = "id", updatable = false, nullable = false)
private Integer id;
private String name;
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "dogs")
private Set<Owner> owners= new HashSet<>();
}
在Owner实体中将原因名称标记为主键的原因是,由于@Inheritance注释表示的旧版继承关系。子类通过名称字段连接到基类。这是其中一个实体的示例:
@Entity
@Table(name = "woman")
public class Woman extends Owner {
private String height;
private String age;
}
由于某些原因,@ ManyToMany关系的第一个@JoinColumn批注中的referencedColumnName参数未生效。似乎默认使用实体主键,即当前的名称字段。
根据Hibernate JPA 2.1 Java文档的referencedColumnName自变量(Javadoc):
(可选)此外键列引用的列的名称。
- 与此处描述的情况以外的实体关系映射一起使用时,所引用的列在目标实体的表中。
- 与单向OneToMany外键映射一起使用时,被引用的列在源实体的表中。
- 在JoinTable批注中使用时,引用的键列在拥有实体的实体表中;如果联接是反向联接定义的一部分,则在反向实体中。
- 在CollectionTable映射中使用时,引用的列在包含集合的实体的表中。
默认值(仅在使用单个连接列的情况下适用):与引用表的主键列相同的名称。
我最终遇到这样的异常,因为它试图比较关系表中的整数id和所有者表中的字段名。
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: integer = name_id_t
注意:name_id_t是在postgres中定义的自定义名称类型。
除了用于双向的ManyToMany JoinTable关系的@Id注释字段之外,是否可以使用其他任何字段?