我的两个表(在SQL Server中):
create table cluster (
id bigint primary key identity(1,1),
name varchar(100)
)
create table cluster_member (
cluster_id bigint,
member_name varchar(100)
)
表cluster_member没有id。列cluster_id就像一个外键,引用了集群表中的id列。
我使用Hiberate Tools生成2个@Entity类和一个@Embeddable类。我添加了一些类变量和@OneToMany和@ManyToOne注释试图加入这两个表。但我得到一个错误说:
org.hibernate.MappingException: Foreign key (FK_hk6sas3oycvcljwbjar7p9ky3:cluster_member [cluster_id,member_name])) must have same number of columns as the referenced primary key (cluster [id])
错误信息非常清楚。但我不知道如何解决它。请帮忙。
这是我的代码:
Cluster.java :
@Entity
@Table(name = "cluster" )
public class Cluster implements java.io.Serializable {
private long id;
private String name;
private Set<ClusterMember> members;
@Id
@Column(name = "id", unique = true, nullable = false)
public long getId() {
return this.id;
}
@Column(name = "name", length = 100)
public String getName() {
return this.name;
}
@OneToMany(mappedBy = "id")
public Set<ClusterMember> getMembers() {
return members;
}
}
ClusterMember.java :
@Entity
@Table(name = "cluster_member" )
public class ClusterMember implements java.io.Serializable {
private ClusterMemberId id;
private Cluster cluster;
@EmbeddedId
@AttributeOverrides({ @AttributeOverride(name = "clusterId", column = @Column(name = "cluster_id")),
@AttributeOverride(name = "memberName", column = @Column(name = "member_name", length = 100)) })
public ClusterMemberId getId() {
return this.id;
}
@ManyToOne
@JoinColumn(name = "cluster_id")
public Cluster getCluster() {
return cluster;
}
}
ClusterMemberId.java :
@Embeddable
public class ClusterMemberId implements java.io.Serializable {
private Long clusterId;
private String memberName;
@Column(name = "cluster_id")
public Long getClusterId() {
return this.clusterId;
}
@Column(name = "member_name", length = 100)
public String getMemberName() {
return this.memberName;
}
}
主要功能:
@SuppressWarnings("deprecation")
public static void main(String[] args) {
sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria("my.hibernate.table.Cluster");
criteria.add(Restrictions.like("name", "%ABC%"));
@SuppressWarnings("unchecked")
List<Cluster> clusters = criteria.list();
for (Cluster cluster: clusters) {
System.out.println(cluster.toString());
}
tx.commit();
sessionFactory.close();
}
hibernate.cfg.xml中
<mapping class="my.hibernate.table.Cluster" />
<mapping class="my.hibernate.table.ClusterMember" />
答案 0 :(得分:2)
尝试更改此内容:
@OneToMany(mappedBy = "id")
public Set<ClusterMember> getMembers() {
return members;
}
到
@OneToMany(mappedBy = "cluster")
public Set<ClusterMember> getMembers() {
return members;
}
并在关联的ManyToOne映射上将insertable / updatable添加为false。
@ManyToOne
@JoinColumn(name = "cluster_id", insertable="false", updatable="false")
public Cluster getCluster() {
return cluster;
}
因为您对ClusterMember.id并不感兴趣,而是在FK链接回Cluster。
在Hibernate中,您不能将相同的列用于不同的映射。 “ClusterMember”已经将“cluster_id”用于@Id属性,因此如果您计划使用ManyToOne关联,则需要指示Hibernate忽略对此目的的任何更改(应忽略插入和更新)。
对于具有备用关联映射的复合标识符,您也可以使用Hibernate's @MapsId annotation。