2011-10-24 8 views
0

私は2つの他のテーブル間で単純な "結合テーブル"を使用してHibernate 4を使用しています。あなたは2つの類似のテーブル、単純なIDに加えて名前を見ることができるようにJPA/Hibernate: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; 

    ... 
} 

:ここではJPA 1.0互換性の実体です。今の相互接続エンティティ:

@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; 

    ... 
} 

注意ここ@Column... , insertable = false, updatable = false。次のテストコード

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(); 
    } 
} 

を実行している場合

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; 
    } 

    ... 
} 

... Hibernateはtrans.commit();に本当に奇妙な例外で失敗:

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 

テストの構成は、Hibernate 4.0.0.CR4ですHSQLDB 2.0などです。また、と非常に同じ JDBC例外を使用してMySQL 5でこれをテストしましたので、明らかにHibernateは間違ったコードを生成しています。

これを解決するための回避策は、..., insertable = false, updatable = falseを関係「@JoinColumn」に入れることですが、実際には私が望むものではありません。

これはHibernateのバグですか?上記のコードは...

+0

HibernateはIdClassと複数の@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 –

答えて

5

JPAの観点から適切でなければなりませんそれはバグです:

https://hibernate.onjira.com/browse/JPA-24

私はJPAのリファレンス実装のEclipseLink 2.3でこれをテストし、それが完璧に動作します。