0

我有一个@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;
        }
    }
}
4

1 回答 1

3

抱歉各位,问题如下:

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

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

因为@PrePersist似乎甚至在事务完成之前就立即调用了它,因此那里没有问题。

于 2013-05-21T12:29:16.250 回答