Java org.hibernate.AnnotationException: 引用的外键列数错误。应该是 2

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24052580/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 09:54:01  来源:igfitidea点击:

org.hibernate.AnnotationException: A Foreign key refering has the wrong number of column. should be 2

javahibernatehibernate-mappinghibernate-annotations

提问by chiranjeevigk

Table details

表详细信息

I have the tables as in the screenshot above

我有上面截图中的表格

Class are written as below

类写如下

@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;  
} 

Note not added getter and setters

注意没有添加 getter 和 setter

and test code as below

和测试代码如下

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());  
            }  
        }  

I am getting the below exception

我收到以下异常

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)  

i came to know i should have the 2 attributes in FilterAttribute class to hold the composite key.. But how can we do that?

我开始知道我应该在 FilterAttribute 类中拥有 2 个属性来保存复合键..但是我们怎么做呢?

采纳答案by StanislavL

@Entity  
public class ObjectAttribute {  
    @Id  
    private int id;  
    @Id  <------------------------ try to remove this annotation
    @ManyToOne  
    @JoinColumn(name="objectId")  
    private Object object;  
    private String name;  
}  

It thinks your ObjectAttribute has 2 ids compound key

它认为你的 ObjectAttribute 有 2 个 ids 复合键

UPDATE: If it really has compound multi column primary key you should reference both columns

更新:如果它真的有复合多列主键,你应该引用两列

回答by JamesENL

Your problem is that you are specifying multiple ID's for your entities. You only need to have the @Idannotation on the field that represents the object's primary key. By annotating fields with @ManyToOneor @OneToManyHibernate will treat that field as a foreign key without you having to do anything. If you remove the extra @Idfields, everthing should start working.

您的问题是您为实体指定了多个 ID。您只需要@Id在表示对象主键的字段上进行注释。通过使用@ManyToOne或注释字段,@OneToManyHibernate 会将该字段视为外键,而您无需执行任何操作。如果您删除额外的@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;
}

回答by Aviad

If you would like to use composite key this is not the way to do it

如果您想使用复合键,这不是这样做的方法

@Entity  
public class ObjectAttribute {  
    @Id  
    private int id;  
    @Id  
    @ManyToOne  
    @JoinColumn(name="objectId")  
    private Object object;  
    private String name;  
}

You have 2 times tag @id, So you need to remove of create composite key with @IdClass annotation if you would like that(not suggested).

您有 2 个标记 @id,因此如果您愿意(不建议),您需要使用 @IdClass 注释删除创建复合键。

You need to create class that contain 2 keys that will hold composite key

您需要创建包含 2 个键的类,这些键将保存复合键

public class CompositeKey {
    private int id; 
    private Object object;  

    //getters and setter
}

After that you will define the key in your entity

之后,您将在实体中定义密钥

@Entity  
@IdClass(CompositeKey.class)
public class ObjectAttribute {  
    @Id  
    private int id;  
    @Id  
    @ManyToOne  
    @JoinColumn(name="objectId")  
    private Object object;  
    private String name;  
}

This is something like that.. But from my experience this thing is not the best things and not suggested to use even by hibernate, Just find another solution to use it.. Or to use his id

这是类似的东西..但根据我的经验,这东西不是最好的东西,即使是休眠也不建议使用,只需找到另一个解决方案来使用它..或者使用他的id

Hope that helps

希望有帮助

回答by Kunwar Babu

@Entity  
public class ObjectAttribute {  
@Id  
private int id;  
@Id  
@ManyToOne  
@JoinColumn(name="objectId")  
private Object object;  
private String name;  

}

}

Use only one @Id in entity if you need both then use both the columns name

如果您需要同时使用两个列名,则在实体中仅使用一个 @Id