Reputation: 414
can anyone tell me where is the error in this example
@Entity
@Table(name = "ITEM")
public class Item implements Serializable
{
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@Column(name = "NAME")
private String name;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "ID_ITEM",referencedColumnName="ID")
private List<ItemDetail> itemDetails;
second class
@Entity
@Table(name = "ITEM_DETAIL")
public class ItemDetail implements Serializable
{
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@Column(name = "NAME")
private String name;
@Column(name = "ID_ITEM")
private Long itemId;
and the db
COMMIT;
CREATE TABLE item(
id serial PRIMARY KEY,
name VARCHAR(16)
);
CREATE TABLE item_detail(
ID serial PRIMARY KEY,
NAME VARCHAR(16),
ID_ITEM serial REFERENCES item (id)
);
COMMIT;
The error i got is
Hibernate: select nextval ('hibernate_sequence')
Hibernate: select nextval ('hibernate_sequence')
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into ITEM (NAME, ID) values (?, ?)
Hibernate: insert into ITEM_DETAIL (ITEM_ID, NAME, ID) values (?, ?, ?)
Hibernate: insert into ITEM_DETAIL (ITEM_ID, NAME, ID) values (?, ?, ?)
Exception in thread "main" org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at com.mkyong.common.App.main(App.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:115)
Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into ITEM_DETAIL (ITEM_ID, NAME, ID) values (NULL, id1, 161) was aborted. Call getNextException to see the cause.
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2530)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1317)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:350)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2592)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 13 more
Process finished with exit code 1
It's obviously that item_id is null but why??
Thanks Regards
Upvotes: 0
Views: 3009
Reputation: 1245
Use nullable = false
to tell Hibernate that the join column cannot be null:
@Entity
@Table(name = "ITEM")
public class Item implements Serializable {
// ...
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "ID_ITEM", referencedColumnName = "ID", nullable = false)
private List<ItemDetail> itemDetails;
// ...
}
and remove the itemId
property from ItemDetail
as it is already mapped by the @JoinColumn
annotation. If you need the itemId
, then use a bi-directional relationship (hold a reference to the entire Item
object, not just the ID).
Upvotes: 1
Reputation: 41165
Having ITEM_ID mapped as a column in ItemDetail
is a bit odd, and mapping it that way might might be the source of the problem. Nothing is telling the ItemDetail
class that that field should be populated with a proper id for the parent Item
, including that it shouldn't be null.
If the detail doesn't need to know about the parent, you might be able to just omit that field in the ItemDetail
java code altogether. The field in the table should be populated as a consequence of the relation.
It's more common to map this sort of thing as a bidirectional association, so that you have a @OneToMany
relation of Item
to ItemDetail
and a @ManyToOne
relation of ItemDetail
to Item
, and the relations can be navigated in Java. If the ItemDetail
does need to know about the parent item, you should do it this way.
This is described somewhere in the Hibernate Annotations Reference section on mapping associations.
Upvotes: 1
Reputation: 518
@backebg: can you check your db script and let us know that you executed exactly same in Database. If yes then either correct your entities to use "ID_ITEM" or item_detail table to use 'ITEM_ID' instead 'ID_ITEM'. thanks
Upvotes: 1