使用JPA使实体成为只读的正确方法是什么?我希望我的数据库表永远不会以编程方式进行修改.
我想我明白我应该锁定我的对象LockModeType.READ.从数据库中检索后,是否可以使用注释使我的实体直接锁定?或者我是否必须乱用并覆盖我的特定实体的通用DAO?
Nic*_*las 45
解决方案是使用基于字段的注释,将您的字段声明为protected仅提议公共getter.这样做,您的对象无法更改.
(此解决方案不是特定于实体的,它只是构建不可变对象的一种方法)
sla*_*dan 35
您可以使用JPA生命周期监听器为您的实体创建防弹安全网.
在您的实体中添加EntityListener如下:
@Entity
@EntityListeners(PreventAnyUpdate.class)
public class YourEntity {
// ...
}
Run Code Online (Sandbox Code Playgroud)
实现你的EntityListener,如果发生任何更新,则抛出异常:
public class PreventAnyUpdate {
@PrePersist
void onPrePersist(Object o) {
throw new RuntimeException("...");
}
@PreUpdate
void onPreUpdate(Object o) {
throw new RuntimeException("...");
}
@PreRemove
void onPreRemove(Object o) {
throw new RuntimeException("...");
}
}
Run Code Online (Sandbox Code Playgroud)
And*_*w B 21
如果你的JPA实现是休眠的 - 你可以使用hibernate实体注释
@org.hibernate.annotations.Entity(mutable = false)
Run Code Online (Sandbox Code Playgroud)
显然,这会将你的模型与休眠联系起来.
Tob*_*san 19
Hibernate还有一个org.hibernate.annotations.Immutable可以放在类型,方法或字段上的注释.
DaT*_*oop 13
我认为你所寻找的是你的实体是永恒的.Hibernate支持这个; JPA(至少JPA 1.0)没有.我想你只能通过提供getter来控制它,并确保getter只返回不可变的值.
这可能会让我失望,因为我总是倾向于建议它,但您可以通过多种方式使用AspectJ来强制执行此操作:
要么自动化Mac的解决方案(使AspectJ注入@Column注释):
declare @field : (@Entity *) *.* : @Column(insertable=false);
Run Code Online (Sandbox Code Playgroud)
或者为所有对set方法的访问声明编译器错误:
declare error : execution((@Entity *) *.set*(*) );
Run Code Online (Sandbox Code Playgroud)
缺点:您需要在构建中添加AspectJ编译,但如果您使用ant或maven则很容易
小智 5
如果您正在使用 spring-data 或以其他方式使用存储库模式,请不要在该特定实体的存储库中包含任何保存/更新/创建/插入/等方法。这可以通过具有只读实体的基类/接口和扩展可更新实体的只读实体的可更新基类/接口来概括。正如其他发布者指出的那样,setter 也可能是非公开的,以避免开发人员意外设置他们无法保存的值。
| 归档时间: |
|
| 查看次数: |
80020 次 |
| 最近记录: |