我有如上面屏幕截图中的表格
类编写如下
@Entity
public class Object {
@Id
private int id;
private String name;
@OneToMany(mappedBy="object",fetch=FetchType.LAZY)
private List<ObjectAttribute> attrubuteList;
}
@Entity
public class ObjectAttribute {
@Id
private int id;
@Id
@ManyToOne
@JoinColumn(name="objectId")
private Object object;
private String name;
}
@Entity
public class Filter {
@Id
private int filterId;
@ManyToOne
@JoinColumn(name="ObjectId")
private Object object;
private String filterName;
@OneToMany(mappedBy="filter")
private Set<FilterAttribute> filterValues;
}
@Entity
public class FilterAttribute implements Serializable {
@Id
private int filterAttrId;
@Id
@ManyToOne
@JoinColumn(name="objectId")
private Object object;
@Id
@ManyToOne
@JoinColumn(name="filterId")
private Filter filter;
@Id
@ManyToOne
@JoinColumn(name="attributeId")
private ObjectAttribute attribute;
private String value;
}
注意没有添加getter和setter
并测试代码如下
List<Object> list = sess.createCriteria(Object.class).list();
for(Object ob: list)
{
System.out.println("Object name : "+ ob.getName());
List<ObjectAttribute> attList = ob.getAttrubuteList();
for (Iterator iterator = attList.iterator(); iterator.hasNext();) {
ObjectAttribute objectAttribute = (ObjectAttribute) iterator
.next();
System.out.println(objectAttribute.getName());
}
}
我收到以下异常
Caused by: org.hibernate.AnnotationException: A Foreign key refering test.rest.ObjectAttribute from test.rest.FilterAttribute has the wrong number of column. should be 2
at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:450)
我开始知道我应该在FilterAttribute类中拥有2个属性来保存复合键。但是我们怎么能这样做呢?
答案 0 :(得分:10)
@Entity
public class ObjectAttribute {
@Id
private int id;
@Id <------------------------ try to remove this annotation
@ManyToOne
@JoinColumn(name="objectId")
private Object object;
private String name;
}
它认为你的ObjectAttribute有2个ID复合键
更新:如果它确实有复合多列主键,则应引用两列
答案 1 :(得分:0)
您的问题是您为实体指定了多个ID。您只需要在表示对象主键的字段上添加@Id
注释。通过使用@ManyToOne
或@OneToMany
注释字段,Hibernate会将该字段视为外键,而无需执行任何操作。如果您删除了额外的@Id
字段,则应该开始工作。
@Entity
public class Object {
@Id
private int id;
private String name;
@OneToMany(mappedBy="object",fetch=FetchType.LAZY)
private List<ObjectAttribute> attrubuteList;
}
@Entity
public class ObjectAttribute {
@Id
private int id;
@ManyToOne
@JoinColumn(name="objectId")
private Object object;
private String name;
}
@Entity
public class Filter {
@Id
private int filterId;
private String filterName;
@ManyToOne
@JoinColumn(name="ObjectId")
private Object object;
@OneToMany(mappedBy="filter")
private Set<FilterAttribute> filterValues;
}
@Entity
public class FilterAttribute implements Serializable {
@Id
private int filterAttrId;
@ManyToOne
@JoinColumn(name="objectId")
private Object object;
@ManyToOne
@JoinColumn(name="filterId")
private Filter filter;
@ManyToOne
@JoinColumn(name="attributeId")
private ObjectAttribute attribute;
}
答案 2 :(得分:0)
如果你想使用复合键,这不是这样做的方法
@Entity
public class ObjectAttribute {
@Id
private int id;
@Id
@ManyToOne
@JoinColumn(name="objectId")
private Object object;
private String name;
}
你有2次标记@id,所以你需要删除带有@IdClass注释的创建复合键,如果你愿意的话(不建议)。
您需要创建包含2个键的类,这些键将包含复合键
public class CompositeKey {
private int id;
private Object object;
//getters and setter
}
之后,您将在实体中定义密钥
@Entity
@IdClass(CompositeKey.class)
public class ObjectAttribute {
@Id
private int id;
@Id
@ManyToOne
@JoinColumn(name="objectId")
private Object object;
private String name;
}
就是这样......但是根据我的经验,这个东西不是最好的东西,甚至不建议使用hibernate,只是找到另一个使用它的解决方案..或者使用他的id
希望有所帮助
答案 3 :(得分:0)
@Entity
public class ObjectAttribute {
@Id
private int id;
@Id
@ManyToOne
@JoinColumn(name="objectId")
private Object object;
private String name;
}
如果您需要两个@Id,请在实体中仅使用一个@Id,然后同时使用列名