Spring Data JPA - 如何在检索后设置瞬态字段

问题描述 投票:0回答:4

使用 Spring Data JPA 的

JpaRepository
方法获取实体后,例如
findOne
findBy...
等,我想知道自动执行一些自定义代码(例如初始化一些瞬态字段)的最佳方法是什么。

换句话说,假设我有一个带有

fullName
瞬态字段的 User 实体,从数据库获取后应将其设置为
firstName
lastName
的串联,我该怎么办?

spring hibernate jpa spring-data spring-data-jpa
4个回答
10
投票

首先,如果您想要全名,只需编写一个动态连接名字/姓氏的方法即可。它不一定是一个字段。

如果您确实需要对实体加载进行一些处理,请注册一个

@PostLoad
实体生命周期回调:

public class MyEntity{

     @PostLoad
     //invoked by framework on entity load.
     public void doStuff(){
         fullName =  forename + " " + surname;   
     }

     //alternative
     public String getFullName(){
         return forename + " " + surname;
     }

https://en.wikibooks.org/wiki/Java_Persistence/Advanced_Topics#Example_of_Entity_event_annotations


3
投票

您可以使用

@Access(AccessType.Property)
理想地设置瞬态场。

您通常必须在 setter 方法中提及

@Access(AccessType.Property)
,然后您可以在该 setter 方法中设置该瞬态字段的值。

或者在存储库的情况下,您可以很好地编写类似这样的

JPQL

@Query("SELECT new Hello(a.x*a.y,a.x,a.y)FROM Hello a WHERE t.value = :value")

然后在构造函数中用

transient variable
 设置这个 
a.x*a.y

的值

1
投票

我自己没有尝试过,但似乎 @PostLoad 注释可以帮助您在从数据库检索业务对象后执行代码以更改业务对象的状态。

但在您的具体情况下,我将简单地创建一个方法 getFullName 来连接firstName和secondName,而不将值存储在bean中。


0
投票

我遇到了同样的问题,我找到了适合我的用例的正确解决方案,该解决方案根本不需要使用 Transient 注释。

我所做的是创建两个类,其中一个是另一个类的子集。两个类都引用相同的数据库表,但子集类不包含瞬态属性。 所以我所有的相关实体都指的是子集类。但是当我明确想要设置或获取瞬态属性时,我使用原始的超集类。

// SUPERSET-CLASS
@Entity
@Table(name = "data_object")
public class DataObject {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(nullable=false, name="id")
   public Long id; 
   public String name;
   
   @JsonIgnore
   @Basic(fetch = FetchType.LAZY)
   public byte[] data;
   
 }

// SUBSET-CLASS
@Entity
@Table(name = "data_object")
public class DataObject_Subset {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(nullable=false, name="id")
   public Long id; 
   public String name;
 }
© www.soinside.com 2019 - 2024. All rights reserved.