当前位置: 首页 > 知识库问答 >
问题:

尝试保存没有自动生成Id的Hibernate实体时发生异常

白成济
2023-03-14

我有两个实体,我想保存到数据库中,付款和付款项。付款可以有更多的付款项目。

主要实体:

@Entity(name = "payment")
public class PaymentEntity {
    @Id
    private UUID id;

    @NotNull   // if I remove this... interesting things happen
    @OneToMany(cascade = CascadeType.ALL)
    @Valid
    private List<PaymentItemEntity> items;

    // getters, setters
}

第二个实体:

 @Entity(name = "payment_item")
 public class PaymentItemEntity {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;

      private String code;
 }

所以,我用1个PaymentItem填充一个Payment,并尝试保存它。请注意,Payment没有自动生成的ID,我从其他地方获取ID并手动设置。

现在,当我试图保存它时,Hibernate会转到数据库,查看是否存在一个现有条目及其项(不是,数据库是空的)。

我知道这一点,因为我打开了Hibernate调试日志,我看到:

2018-06-22 14:34:33.939 DEBUG 3915 --- [nio-8100-exec-2] o.h.e.i.DefaultMergeEventListener        : EntityCopyObserver strategy: disallow
2018-06-22 14:34:33.940 DEBUG 3915 --- [nio-8100-exec-2] org.hibernate.loader.Loader              : Loading entity: [ro.vdin.entity.PaymentEntity#60587d84-3ae6-3f1e-b63e-fa8b6658d669]

然后它失败了,只有一个例外:

javax.validation.ConstraintViolationException: Validation failed for classes [ro.vdin.entity.PaymentEntity] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='must not be null', propertyPath=items, rootBeanClass=class ro.vdin.entity.PaymentEntity, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:140) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:80) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:205) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:82) ~[hibernate-core-5.2.14.Final.jar:5.2.14.Final]

即使我的初始支付实体有一个包含1个项目的列表(因此,它不是空的)。

有趣的是,如果我删除@NotNull注释,所有内容都会保存到db中——Payment、PaymentItem以及它们之间的关系(Hibernate创建了一个正确填充的关联表)。

(基本上,由于实体的id已设置,hibernate会尝试合并实体,而不是将其保存到数据库中。)

为了在列表项上保留@NotNull注释,我可以做些什么?我可以做些什么,使它不从数据库加载任何内容,并直接保存吗?

共有1个答案

堵彬彬
2023-03-14

例如,您没有传递join column@joinColumn。

@Entity(name = "payment")
public class PaymentEntity {
@Id
@GeneratedValue(strategy = IDENTITY)
private UUID id;
@NotNull   
@OneToMany(cascade = CascadeType.ALL)
@Valid
private List<PaymentItemEntity> items;
// getters, setters
}
 //Child Class
@Entity(name = "payment_item")
public class PaymentItemEntity {
  @Id
  @GeneratedValue(strategy = IDENTITY)
  private Long id;
  private String code;
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "id")// for Example i have passed id you have pass join column name
  private PaymentEntity paymentEntity;
    // getters, setters
}
 类似资料:
  • 问题内容: 启动Java应用程序时,尝试保存图像时出现异常。但是,在Eclipse中,一切正常。该应用程序是使用fatjar构建的,并且还选择了必需的库(jar_imageio.jar和ij.jar)进行导出。 我尝试使用ImageIO和ImageJ: a。)ImageIO: b。)ImageJ: 问题答案: 正如@Victor说的,我认为您应该看看 我昨天才遇到这个问题,这很棘手。有类似的问题在

  • 问题内容: 有人知道如何从1开始生成,以便下一个对象具有2,依此类推吗? 我尝试了以下方法,但不起作用: 问题答案: 您需要一个 静态的 类成员来跟踪上次使用的索引。确保还实现一个复制构造函数: 更新: 正如@JordanWhite建议的那样,您可能希望使static计数器成为 atomic ,这意味着可以安全地同时使用(即一次在多个线程中使用)。为此,将类型更改为: 增量读取和复位操作变为:

  • 我正在与用户一起制作一个应用程序。用户有一个id,该id使用以下Hibernate注释自动分配: 这一切都很好,但问题是,每次我运行应用程序(同时添加同一个用户)时,它都会为用户分配一个新id,而不管该用户是否已经存在。 我该怎么做才能使现有用户在每次运行应用程序时都不会获得新id,而不必要求所有用户单独检查他们的用户名? 提前谢谢。 编辑 更多的一些代码示例(这里我只写相关的代码)。 用户: 带

  • 子类: 我将它保存在我的DAO中,如下所示: 当我试图保存对象ship,它会给我以下错误:

  • 大约34小时前,我生成了一个签名的apk,但现在,我无法生成一个签名的apk,我不知道如何解决这个问题。请帮忙 这是我的输出消息 > 错误:任务“:app:LintVitalRelease”执行失败。 尝试:使用--stacktrace选项运行以获取堆栈跟踪。使用--info或--debug选项运行以获取更多日志输出。使用--scan运行以获得完整的见解。 这是我的Build.Gradle(应用程

  • 问题内容: 我正在使用以下时间戳格式: 以下方法可以正常工作: 而且,当我使用该格式字符串传递时间戳时,它返回,例如: 然后,我需要再次从该字符串映射到时间戳,本质上是相反的操作。我知道我可以使用和及其方法,但是如果可能的话,我宁愿坚持使用样式格式。 我写了这段代码(相当hacky),它适用于某些格式,但不适用于特定格式: 在第二部分,它失败了。 堆栈跟踪: 有没有一种更简单的方法可以在不利用我的