我在兩個其他表之間使用Hibernate 4時使用了簡單的「連接表」。這裏是JPA 1.0兼容的實體:JPA/Hibernate:java.sql.SQLException:JDBC調用中的無效參數:參數索引超出範圍
@Entity
@Table(name = "Companies")
public class Company
{
@Id
@Column
private Integer id;
@Column
private String name;
...
}
和
@Entity
@Table(name = "PQs")
public class PQ implements Serializable
{
@Id
@Column
private Integer id;
@Column
private String name;
...
}
正如你可以看到兩個類似的表,只是一個簡單的ID加名。現在互連實體:
@Entity
@Table(name = "Partnerships")
@IdClass(value = PartnershipId.class)
public class Partnership implements Serializable
{
@Id
@Column(name = "pq_id", insertable = false, updatable = false)
private Integer pqId;
@Id
@Column(name = "company_id", insertable = false, updatable = false)
private Integer companyId;
@Column(name = "ordinal_nbr")
private Integer ordinalNbr;
@ManyToOne
@JoinColumn(name = "pq_id", referencedColumnName = "id")
private PQ pq;
@ManyToOne
@JoinColumn(name = "company_id", referencedColumnName = "id")
private Company company;
...
}
注意... , insertable = false, updatable = false
上@Column
這裏。
public class PartnershipId implements Serializable
{
private Integer pqId;
private Integer companyId;
public PartnershipId()
{
}
public PartnershipId(Integer pqId, Integer companyId)
{
this.pqId = pqId;
this.companyId = companyId;
}
...
}
當trans.commit();
運行下面的測試代碼
public class Main
{
private static String PERSISTENCE_UNIT_NAME = "standalonePu";
private static EntityManagerFactory emf;
private static EntityManager em;
private static EntityTransaction trans;
public static void main(String[] args)
{
setUp(PERSISTENCE_UNIT_NAME);
trans.begin();
PQ detachedPq = new PQ(1, "Test PQ");
Company detachedCompany = new Company(1, "Test Company");
PQ pq = em.merge(detachedPq);
Company company = em.merge(detachedCompany);
Partnership detachedPartnership = new Partnership(1, 1, 1);
detachedPartnership.setPQ(pq);
detachedPartnership.setCompany(company);
Partnership partnership = em.merge(detachedPartnership);
partnership = em.find(Partnership.class, new PartnershipId(1, 1));
System.out.println("Persistent partnership = ("
+ partnership.getPQId() + ", "
+ partnership.getCompanyId() + ", "
+ partnership.getOrdinalNbr() + ")");
trans.commit();
close();
}
private static void setUp(String puName)
{
emf = Persistence.createEntityManagerFactory(puName);
em = emf.createEntityManager();
trans = em.getTransaction();
}
private static void close()
{
em.close();
emf.close();
}
}
... Hibernate的失敗,一個很奇怪的例外:
ERROR: Invalid argument in JDBC call: parameter index out of range: 4
Exception in thread "main" javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:90)
at main.Main.main(Main.java:44)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Invalid argument in JDBC call: parameter index out of range: 4
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1347)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1280)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:78)
... 1 more
Caused by: org.hibernate.exception.GenericJDBCException: Invalid argument in JDBC call: parameter index out of range: 4
at org.hibernate.exception.internal.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:148)
at org.hibernate.exception.internal.SQLStateConverter.convert(SQLStateConverter.java:136)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:124)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:131)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:80)
at $Proxy12.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:82)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:305)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:300)
at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:358)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2599)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2836)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3276)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:80)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:273)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:265)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:186)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:344)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1084)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:319)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:100)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:173)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:73)
... 1 more
Caused by: java.sql.SQLException: Invalid argument in JDBC call: parameter index out of range: 4
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.outOfRangeArgument(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.checkSetParameterIndex(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.setInt(Unknown Source)
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:601)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:124)
... 22 more
Caused by: org.hsqldb.HsqlException: Invalid argument in JDBC call: parameter index out of range: 4
at org.hsqldb.error.Error.error(Unknown Source)
... 31 more
測試的配置中是休眠4.0.0.CR4和HSQLDB 2.0。我也用MySQL 5測試了這個,和非常相似,所以顯然Hibernate產生了不正確的代碼。
解決此問題的解決方法是將..., insertable = false, updatable = false
放到關係'@JoinColumn
s上,但這不是我真正想要的。
所以,這是一個Hibernate的bug?上面的代碼應該是正確的,從JPA的角度...
Hibernate並不真正推薦使用IdClass和Multiple @Id屬性。如果使用組件類型表示,這將會更好。 –
你有沒有參考你的陳述?以上是普通的JPA 1.0,Hibernate聲稱自3.5版開始就兼容JPA 2.0。請注意,我想留在這裏(JPA)。 – Kawu
http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping-identifier –