当前位置: 首页 > 面试题库 >

JPA / Hibernate preUpdate不会更新父对象

隗驰
2023-03-14
问题内容

在我的应用程序中,我定义了以下类:

@Entity
@Table(name = "forums")
public class Forum {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;

    private String name;
    private Date lastActivity;

    @OneToMany(mappedBy = "forum", cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE })
    private List<Post> posts;
@Entity
@Table(name = "posts")
public class Post {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id;

    private String username;
    private String content;
    private Date creationDate;

    @ManyToOne(optional = false, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
    private Forum forum;

    public Post() {
        creationDate = new Date();
    }

    @PrePersist
    private void onPersist() {
        System.out.println(getClass().getName() + ": onPersist");
        if (creationDate == null) {
            creationDate = new Date();
        }

        forum.setLastActivity(creationDate);
    }

    @PreUpdate
    private void onUpdate() {
        forum.setLastActivity(new Date());
    }

如果我尝试将新帖子添加到论坛实体,lastActivity则数据库将通过@PrePersist回调正确更新字段。但是,如果我尝试使用以下代码更新发布实体:

  entityManager.getTransaction().begin();
  Post post = entityManager.find(Post.class, "postId");
  post.setContent("New post text");
  entityManager.merge(post);
  entityManager.getTransaction().commit();

仅帖子数据被更新,lastActivity字段值不变。我认为@PreUpdate方法应该有效,并更新论坛实体。这是错误还是我错过了什么?


问题答案:

这不是错误,即使快速尝试也可以达到您预期的效果。不利的消息是由于以下原因,不能保证它能正常工作:

从JPA 2.0规范的第93页:

通常,可移植应用程序的生命周期方法不应调用EntityManager或Query操作,访问其他实体实例或在同一持久性上下文中修改关系。[43]
生命周期回调方法可以修改在其上调用它的实体的非关系状态。

和第95页:

是否在将生命周期事件级联到相关实体之前或之后调用回调方法取决于实现。应用程序不应依赖于此顺序。



 类似资料:
  • 我正在这里学习“带有链接实体生命周期的双向多对多”教程https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/hibernate_user_guide.html#associations-many-to-many。但是,我使用的是Spring JPA而不是实体管理器。当我使用repository接口删除一个地址时,这并不是不删除

  • 我的实体更新有问题。如你所见,我有三个实体。 包含类中的列表。 包含类中的列表。 从我的SQL语句中可以看到,字段和是唯一的。我的表中只允许该组合的一行。 当我用类的新列表更新父实体()时,我希望Hibernate删除旧列表本身并创建新实体。一个一个地更新孩子是有点困难的。这就是为什么我要直接删除所有相关的孩子。 当我更新并为其提供包含具有唯一名称的和(数据库中已存在的实体)组合的列表时,我会出现

  • 问题内容: 我正在尝试将JProgressBar添加到我的程序中,但不会更新!仅当原因为100%时,该值才会更改。这是我的方法。 更改进度栏的值位于上述方法的底部。 这就是我所谓的方法。 编辑:以上根本不是问题,问题之一是程序正在使用整数除法而不是十进制。 问题答案: 是一个整数,也是。因此发生的是小数被截断。你应该做什么,就像 这样做是确保将其除以具有十进制功能的数据类型,该数据类型将返回更具包

  • 我试图让我的JTable显示对扩展AbstractTableModel的TableModel所做的更改。我创建了一个堆来插入所有文档,然后在我的堆数组上应用了一个堆排序,所以这个有序的数组应该是我的TableModel数据。它看起来是这样的: 在方法中,当我调用时,堆内部数组将被销毁,它返回一个和有序节点。因此,当有一个带有节点的有序数组时,我的JTable不会显示数据。现在,如果我不执行,而是从

  • 在我的片段中,我观察到db问卷列表字段: 在我的片段中,我有几个按钮,根据哪个按钮被按下,我在viewModel上调用方法,将设置为标签的字符串传递给按钮。 我的视图模式: 存储库方法: Dao方法: 当我按下按钮时,viewModel方法被调用,并带有参数,该参数应该用于通过搜索房间数据库来更新LiveData,但没有任何内容会被无缘无故地更新。数据库不是空的,所以没有理由在主片段中返回null

  • 问题内容: 我有一段代码 单击“ Hi”消息时,仅组件会继续重新渲染,而组件不会重新渲染。 为什么在状态更改时不重新渲染组件? 我想说,由于它是组件的一个属性而不会发生,但是仍然会被JSX中的组件评估,所以不确定。 完整示例https://codesandbox.io/s/529lq0rv2n(检查控制台日志) 问题答案: 这个问题已经很老了,但是由于您似乎没有得到满意的答案,因此我也会尝试一下。