注释异常:外键引用的列数错误,应该是2。

38

我正在将我的类与数据库中的表进行映射,但运行测试时,出现以下错误:

Caused by: org.hibernate.AnnotationException: A Foreign key refering com.modulos.pvs.acceso.datos.entity.Provincia from com.modulos.pvs.acceso.datos.entity.Ciudad has the wrong number of column. should be 2
    at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:429)
    at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:115)
    at org.hibernate.cfg.Configuration.processEndOfQueue(Configuration.java:1550)
    at org.hibernate.cfg.Configuration.processFkSecondPassInOrder(Configuration.java:1473)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1389)
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:717)
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1541)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1479)
    ... 40 more

这是我的课程:

//    PROVINCIA TABLE
    @Entity
    @Table(name="provincia")
    @NamedQuery(name = "Provincia.findAll", query = "SELECT p FROM Provincia p")
    public class Provincia implements Serializable {

        private static final long serialVersionUID = 1L;

        @EmbeddedId
        private ProvinciaPK id;

        private String nombreProvincia;

        // bi-directional many-to-one association to Region
        @ManyToOne(fetch=FetchType.LAZY)
        @JoinColumn(name = "codRegion")
        private Region region;

        //bi-directional many-to-one association to Ciudad
        @OneToMany(mappedBy="provincia", fetch=FetchType.LAZY)
        private List<Ciudad> ciudad;

    //GETTER AND SETTER

//TABLE CIUDAD
/**
 * The persistent class for the city database table.
 * 
 */
@Entity
@Table(name="ciudad")
@NamedQuery(name = "Ciudad.findAll", query = "SELECT c FROM Ciudad c")
public class Ciudad implements Serializable {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private CiudadPK id;

    private String nombreCiudad;

    // bi-directional many-to-one association to Provincia
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "codProvincia", insertable = false, updatable = false)
    private Provincia provincia;

    //bi-directional many-to-one association to Direcciones
    @OneToMany(mappedBy="ciudad", fetch=FetchType.LAZY)
    private List<Direcciones> direcciones;

//  GETTER AND SETTER

两者都有主键,这些主键都嵌入到类中。

//PROVINCIA PK
/**
 * The primary key class for the provincia database table.
 * 
 */
@Embeddable
public class ProvinciaPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

    private String codProvincia;

    private String codRegion;

    public ProvinciaPK() {
    }
    /getter and setter

//ciudad pk
/**
 * The primary key class for the region database table.
 * 
 */
@Embeddable
public class CiudadPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

    private String codCiudad;

    private String codProvincia;

    public CiudadPK() {
    }
//GETTER AND SETTER

这是我的关系模型数据库

输入图像描述

有人有任何想法吗?如果那不起作用怎么办?

编辑 30/11/2014 - 返回到列表空关联,这是我的 JUnit 测试

Region region = new Region();
            region.setId(new RegionPK("RM","CHL"));

            region.setProvincias(regionDAO.getProvinciaRegion(region));

            System.out.println(region.getProvincias());

这是返回省份关联的方法。

@Transactional(readOnly=true)
@Override
public List<Provincia> getProvinciaRegion(Region region) {
    region = getRegionById(region);
    Hibernate.initialize(region.getProvincias());
    return region.getProvincias();
}

而这些信息已经存储在数据库中

enter image description here

enter image description here

2个回答

65

您的类CiudadPK有两列。 您只使用了@JoinColumn,它仅限于单个列。 您需要使用@JoinColumns并在外键中列出两个列,例如:

// bi-directional many-to-one association to Provincia
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
  @JoinColumn(name = "codProvincia", insertable = false, updatable = false),
  @JoinColumn(name = "codRegion", insertable = false, updatable = false)
})
private Provincia provincia;

您可能也会遇到与 Ciudad 相关的另一个问题,请按照这里的模式进行更正。


你得到一个复合主键,因为你在代码中使用了@EmbeddedId。这不是你的意图吗? - John Ament
如果不是你给我讲解,我会感到困惑,但现在我明白了。 否则,因为现在我尝试在类中返回REGION asociasones列表,但我返回的是一个空列表,你知道为什么吗? 我已经在帖子中编辑了相关信息。 - Elias Vargas
它可以工作,但是当我保存一个新实体“Ciudad”时,为什么会出现“违反唯一约束条件的重复键值”错误,这是为什么? - pierre
谢谢!你帮我节省了时间! - RoutesMaps.com
我因为这个问题来到这里,但我已经使用了JoinColumns,尽管它是OneToOne。那可能是原因吗? - chitgoks
显示剩余3条评论

10
自Java 8(引入@Repeatable)开始,不再需要包装注释@JoinColumns
因此,你可以简单地这样做:
// bi-directional many-to-one association to Provincia
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "codProvincia", insertable = false, updatable = false)
@JoinColumn(name = "codRegion", insertable = false, updatable = false)
private Provincia provincia;

参考资料:

Java 8的新类型注解

重复注解


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接