Hi,
I have a problem running JPA + Hibernate + Oracle, that I am not able to figure out.
Here is a minimal test-case to demonstrate the error I get:
I have a class, say B, with a composite-id of two columns.
One of the id-columns is also a foreign-key to another class, say C.
In Oracle:
Code:
CREATE TABLE C
( C_ID INTEGER,
CONSTRAINT PK_C PRIMARY KEY(C_ID)
);
CREATE TABLE B
( B_PK1 INTEGER,
B_PK2 INTEGER,
CONSTRAINT PK_B PRIMARY KEY (B_PK1, B_PK2),
CONSTRAINT FK_B_C FOREIGN KEY (B_PK1) REFERENCES C (C_ID)
);
In Java, I define the classes B, BPK and C.
I need a ID-class BPK for the primary key of B,
and I also want be able to access the class C directly from the class B:
BPK.java:
Code:
@Embeddable
public class BPK implements Serializable {
@Column(name = "B_PK1")
private Long pk1;
@Column(name = "B_PK2")
private Long pk2;
// ...setters, getters, equals and hashCode() go here...
}
B.java:
Code:
@Entity
@Table(name = "B")
@IdClass(value = BPK.class)
public class B {
@Id
@Column(name = "B_PK1")
Long pk1;
@Id
@Column(name = "B_PK2")
Long pk2;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "B_PK1", referencedColumnName = "C_ID")
private C c;
// ...setters, getters, equals and hashCode() go here...
}
C.java:
Code:
@Entity
@Table(name = "C")
public class C {
@Id
@Column(name = "C_ID")
private Long cId;
// ...setters, getters, equals and hashCode() go here...
}
Now I preload table C with the value 1:
Code:
insert into c values (1);
commit;
Next, run the test-case:
Code:
B b = new B();
b.setPk1(1L);
b.setPk2(new Random().nextLong() % 1000000L);
entityManager.persist(b);
entityManager.flush();
This gives me the exception:
Code:
...
Caused by: java.sql.SQLException: Invalid column index
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
at oracle.jdbc.driver.OraclePreparedStatement.setLongInternal(OraclePreparedStatement.java:4639)
at oracle.jdbc.driver.OraclePreparedStatement.setLong(OraclePreparedStatement.java:4631)
at org.apache.commons.dbcp.DelegatingPreparedStatement.setLong(DelegatingPreparedStatement.java:120)
at org.hibernate.type.LongType.set(LongType.java:65)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:154)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:136)
at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:307)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2036)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2271)
... 50 more
In the log I can see that the error is caused by
insert into b (b_pk1, b_pk2) values (?, ?)
I think this Exception means that Hibernate somehow gets confused and tries to submit more parameter-values
to the INSERT statement than there are ?-place-holders in the SQL-statement,
but I cannot figure out what the reason is.
Anyone can explain exactly what causes this error?
( I am aware that the class B kind of references class C "twice" - both through the BPK.pk1 foreign-key,
and the property B.c, but that is how I gleaned from other examples, that you are supposed
to do in a case like this? )