复合主键的jpa部分也是复合外键的一部分

时间:2013-05-20 10:42:25

标签: java mysql hibernate jpa orm

我在绘制三个JPA实体之间的关系时遇到了问题。首先,我向您展示所涉及的数据库表:

  1. Ciclista

      

    idciclista(PK)
      (其他领域......)

  2. Prueba

      

    idprueba(PK)
      (其他领域......)

  3. Inscripcion

      

    idciclista(PK,FK in Ciclista.idciclista)
       idprueba(PK,FK in Prueba.idprueba,FK in Variante.idprueba)
      idvariante(FK in Variante.idvariante)
      (其他领域......)

  4. 瓦里安特

      

    idprueba(PK,FK in Prueba.idprueba)
      idvariante(PK)
      (其他领域......)

  5. 问题在于突出显示的字段,它是Inscripcion的复合PK的一部分,Prueba中的FK和Variante中的复合FK的一部分,同时都是。

    我的JPA实体:

    @Entity
    @Table(name = "inscripcion")
    @IdClass(value=InscripcionPK.class)
    public class Inscripcion {
        // ATTRIBUTES
        @Column
        private int dorsal;
        @Column
        @Temporal(TemporalType.TIMESTAMP)
        private Date fechaHora;
        @Column
        private int estado;
    
        // RELATIONSHIPS
        @Id
        @ManyToOne
        @JoinColumn(name = "idciclista")
        private Ciclista participante;
        @Id
        @ManyToOne
        @JoinColumn(name = "idprueba", insertable=false, updatable=false)
        private Prueba prueba;
        @ManyToOne
        @JoinColumns({  
            @JoinColumn(name="idprueba"),  
            @JoinColumn(name="idvariante")
        }) 
        private Variante variante;
    
    //Constructors, public getters and setters...
    }
    
    @Embeddable
    public class InscripcionPK implements Serializable {
        private static final long serialVersionUID = -582735882125091352L;
    
        int participante;
        int prueba;
    
        //Public getters and setters, hashcode, equals...
    }
    

    我没有粘贴剩下的映射,因为到目前为止它们没有给我带来任何问题,但它们也引用了当前的实体(双向映射)。

    持久化“Inscripcion”对象时出现以下异常:

    ...
    Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Parameter index out of range (7 > number of parameters, which is 6).
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1306)
        at org.hibernate.ejb.AbstractEntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(AbstractEntityManagerImpl.java:1500)
        at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:109)
        at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53)
        at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:435)
        ... 90 more
    Caused by: org.hibernate.exception.GenericJDBCException: Parameter index out of range (7 > number of parameters, which is 6).
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
        at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
        at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
        at sun.proxy.$Proxy211.setInt(Unknown Source)
        at org.hibernate.type.descriptor.sql.IntegerTypeDescriptor$1.doBind(IntegerTypeDescriptor.java:57)
        at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92)
        at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:280)
        at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:275)
        at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:358)
        at org.hibernate.persister.entity.AbstractEntityPersister.dehydrateId(AbstractEntityPersister.java:2784)
        at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2753)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3025)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3469)
        at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88)
        at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:275)
        at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
        at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:402)
        at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:104)
        ... 92 more
    Caused by: java.sql.SQLException: Parameter index out of range (7 > number of parameters, which is 6).
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:988)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:974)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:919)
        at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3813)
        at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3795)
        at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3840)
        at com.mysql.jdbc.PreparedStatement.setInt(PreparedStatement.java:3784)
        at com.mysql.jdbc.jdbc2.optional.PreparedStatementWrapper.setInt(PreparedStatementWrapper.java:399)
        at com.sun.gjc.spi.base.PreparedStatementWrapper.setInt(PreparedStatementWrapper.java:190)
        at sun.reflect.GeneratedMethodAccessor82.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
    

    如果我在“variante”的@ JoinColum中放入“insertable = false,updatable = false”,我会得到以下异常:

    ...
    Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`projectbike`.`inscripcion`, CONSTRAINT `fk_inscripcion_variante1` FOREIGN KEY (`idvariante`, `idprueba`) REFERENCES `variante` (`idvariante`, `idprueba`) ON DELETE NO ACTION ON UPDATE NO ACTI)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1306)
        at org.hibernate.ejb.AbstractEntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(AbstractEntityManagerImpl.java:1500)
        at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:109)
        at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53)
        at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:435)
        ... 90 more
    Caused by: org.hibernate.exception.ConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`projectbike`.`inscripcion`, CONSTRAINT `fk_inscripcion_variante1` FOREIGN KEY (`idvariante`, `idprueba`) REFERENCES `variante` (`idvariante`, `idprueba`) ON DELETE NO ACTION ON UPDATE NO ACTI)
        at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
        at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
        at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
        at sun.proxy.$Proxy233.executeUpdate(Unknown Source)
        at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3028)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3469)
        at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88)
        at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:275)
        at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
        at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:402)
        at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:104)
        ... 92 more
    Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`projectbike`.`inscripcion`, CONSTRAINT `fk_inscripcion_variante1` FOREIGN KEY (`idvariante`, `idprueba`) REFERENCES `variante` (`idvariante`, `idprueba`) ON DELETE NO ACTION ON UPDATE NO ACTI)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
        at com.mysql.jdbc.Util.getInstance(Util.java:386)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1040)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
        at com.mysql.jdbc.jdbc2.optional.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:875)
        at com.sun.gjc.spi.base.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:125)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
        ... 106 more
    

    我不知道这是否是一个Hibernate错误,如果这个案例没有被JPA支持,或者我错过了一些明显的东西。


    修改

    我也发布了我的Variante类,因为它也有一个复合键。我希望它有所帮助:

    @Entity
    @Table(name="variante")
    @IdClass(value=VariantePK.class)
    public class Variante {
        //ATRIBUTOS
        @Id
        @Column(name="idvariante")
        private short id;
        @Column
        private String nombre;
        @Column
        private Integer longitud;
        @Column
        private Integer desnivelPos;
        @Column
        private boolean mostrarTrack;
    
        //RELACIONES
        @Id
        @ManyToOne(optional = false, cascade=CascadeType.ALL)
        @JoinColumn(name="idprueba")
        private Prueba prueba;
        @ManyToOne(cascade = CascadeType.ALL)
        @JoinColumn(name="idrecorrido")
        private Recorrido recorrido;
        @OneToMany(mappedBy = "variante", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
        private Set<Inscripcion> inscripciones;
    
        // Consructors, getters and setters...
    }
    
    public class VariantePK implements Serializable {
        private static final long serialVersionUID = -3276237020478540672L;
    
        private short id;
        private Integer prueba;
    
        public VariantePK() {
            super();
        }
    
        //Constructors, getters, setters, hashcode, equals...
    }
    

0 个答案:

没有答案