没有在所有实体上调用JPA @PreUpdate

时间:2013-05-21 06:33:58

标签: hibernate jpa

我有一个@MappedSuperclass,其中包含创建和上次修改日期等元数据。我的所有实体都扩展了这个类。该类还有一个使用@PreUpdate注释的方法,该方法在相应的操作之前设置这些属性。

目前令我发疯的是,这项工作适用于实体A和C,但不适用于B.它们都直接扩展了BaseEntity。基本上他们应该表现不同的原因有0。更令人困惑的是,@PrePresist在所有实体上都被正确调用,也就是B。

任何人都知道为什么会这样?这让我疯了......

public class A extends BaseEntity {}

public class B extends BaseEntity {}

public class C extends BaseEntity {}

@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    @Getter
    @Setter(AccessLevel.PROTECTED)
    @Version
    private Long version;

    @Getter
    @Setter(AccessLevel.PROTECTED)
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created")
    private Date created;

    @Getter
    @Setter(AccessLevel.PROTECTED)
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "last_modified")
    private Date lastModified;

    @Getter
    @Setter(AccessLevel.PROTECTED)
    @Column(name = "created_by")
    private String createdBy;

    @Getter
    @Setter(AccessLevel.PROTECTED)
    @Column(name = "last_modified_by")
    private String lastModifiedBy;

    @PreUpdate
    public final void updateMetadata() {
        lastModified = new Date();
        if (SecurityContextHolder.getContext().getAuthentication() != null) {
            lastModifiedBy = SecurityContextHolder.getContext()
                    .getAuthentication().getName();
        }
    }

    @PrePersist
    public final void createMetadata() {
        created = new Date();
        lastModified = created;
        if (SecurityContextHolder.getContext().getAuthentication() != null) {
            final String userName = SecurityContextHolder.getContext()
                    .getAuthentication().getName();
            lastModifiedBy = userName;
            createdBy = userName;
        }
    }
}

1 个答案:

答案 0 :(得分:3)

对不起家伙问题如下:

使用SpringJUnit4ClassRunner进行测试。问题是实体B的测试用@Transactional注释。这意味着@PreUpdate仅在测试完成后调用,因此测试失败。

如果所有实体都以与@Transactional相同的方式注释,则所有实体的行为都是相同的。

对于@PrePersist,它似乎在事务完成之前立即被调用,因此没有问题。