我在绘制三个JPA实体之间的关系时遇到了问题。首先,我向您展示所涉及的数据库表:
Ciclista
idciclista(PK)
(其他领域......)
Prueba
idprueba(PK)
(其他领域......)
Inscripcion
idciclista(PK,FK in Ciclista.idciclista)
idprueba(PK,FK in Prueba.idprueba,FK in Variante.idprueba)
idvariante(FK in Variante.idvariante)
(其他领域......)
瓦里安特
idprueba(PK,FK in Prueba.idprueba)
idvariante(PK)
(其他领域......)
问题在于突出显示的字段,它是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...
}