2011-10-24 133 views
0

我在兩個其他表之間使用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的角度...

+0

Hibernate並不真正推薦使用IdClass和Multiple @Id屬性。如果使用組件類型表示,這將會更好。 –

+0

你有沒有參考你的陳述?以上是普通的JPA 1.0,Hibernate聲稱自3.5版開始就兼容JPA 2.0。請注意,我想留在這裏(JPA)。 – Kawu

+0

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping-identifier –

回答

相關問題