【问题标题】:One to many map in Hibernate - error休眠中的一对多映射 - 错误
【发布时间】:2011-06-18 18:59:46
【问题描述】:

谁能告诉我这个例子的错误在哪里

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

二等

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

和数据库

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;

我得到的错误是

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

很明显 item_id 为空,但为什么呢??

谢谢 问候

【问题讨论】:

  • 你能把hibernate_sequence的定义贴在数据库里吗?
  • 它是在执行创建表的查询时隐式创建的。
  • 查看这一行 原因:java.sql.BatchUpdateException:批处理条目 0 插入 ITEM_DETAIL(ITEM_ID,NAME,ID)值(NULL,id1,161)被中止。调用 getNextException 查看原因。

标签: java hibernate annotations one-to-many


【解决方案1】:

@backebg:你能检查一下你的数据库脚本,让我们知道你在数据库中执行的操作完全相同。如果是,则更正您的实体以使用“ID_ITEM”或 item_detail 表以使用“ITEM_ID”而不是“ID_ITEM”。谢谢

【讨论】:

  • 这是不正确的注释 - 但即使我将实体更改为 ID_ITEM,同样的问题仍然存在 :( 谢谢
  • 在项目实体中它仍然是 ITEM_ID。让我们尝试再次更改它并检查异常,它和以前一样吗?谢谢。
  • Ops.Yes 同样的错误仍然存​​在 :( 例外是那个。谢谢 Asad。
【解决方案2】:

将 ITEM_ID 映射为 ItemDetail 中的列有点奇怪,以这种方式映射它可能是问题的根源。没有什么告诉 ItemDetail 类该字段应该填充父 Item 的正确 id,包括它不应该为空。

如果不需要了解父级的详细信息,您可以完全省略 ItemDetail java 代码中的该字段。表中的字段应根据关系填充。

将此类事物映射为双向关联更为常见,因此您具有ItemItemDetail@OneToMany 关系和ItemDetailItem@ManyToOne 关系,并且这些关系可以在 Java 中导航。如果ItemDetail 确实需要了解父项,您应该这样做。

这在Hibernate Annotations Reference section on mapping associations 的某处有所描述。

【讨论】:

  • 感谢唐的帖子。我会看看。 :)
【解决方案3】:

使用nullable = false告诉Hibernate连接列不能为空:

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

    // ...
}

并从ItemDetail 中删除itemId 属性,因为它已经由@JoinColumn 注释映射。如果您需要 itemId,则使用双向关系(保存对整个 Item 对象的引用,而不仅仅是 ID)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-25
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    相关资源
    最近更新 更多