如何强制hibernate调用setter方法来填充类字段?

时间:2017-03-21 05:52:13

标签: java hibernate jpa

我有一个持久化类,其中有一个瞬态字段代表此类的 API 版本(我为api请求使用的字段的子集)。该字段为@Transient,因为我只使用其他字段来创建它。

问题是hibernate使用默认的空构造函数来实例化类和反射以访问字段...所以我不能在constrorctor上实例化我的瞬态类,也不能调用setter方法

我尝试使用 getter 方法而不是字段来强制hibernate使用setter,但它没有工作

我尝试在字段上使用@Access(AccessType.PROPERTY),但它没有工作

如何强制hibernate调用setter方法来填充类字段?

@Entity
public class User {

    @Transient
    private ApiUser tempUser = new ApiUser ();

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Access(AccessType.PROPERTY)
    @Column(nullable = false)
    private String name;
    @Access(AccessType.PROPERTY)
    @Column(nullable = false, unique = true)
    private String username;
@Access(AccessType.PROPERTY)
    @Column(nullable = false)
    private String userId;

//lots of others fields//
public void setUsername(String username) {
        this.username = username;
        this.tempUser.setUsername(username);
    }
public void setUserId(String userId) {
        this.userId = userId;
        this.tempUser.setId(Long.parseLong(userId));
    }

1 个答案:

答案 0 :(得分:5)

默认情况下,访问类型由您放置标识符注释的位置(@Id)定义。如果你把它放在字段上 - 它将是AccessType.FIELD,如果你把它放在getter上 - 它将是AccessType.PROPERTY。

有时您可能想要注释不是字段而是属性(例如,因为您希望在getter中有一些任意逻辑,或者因为您喜欢这种方式。)在这种情况下,您必须定义一个getter并将其注释为AccessType.PROPERTY

据我所知,如果在任何实体字段/方法上指定AccessType.FIELD或AccessType.PROPERTY,则必须指定整个类的默认行为。这就是为什么你需要在类级别拥有AccessType.FIELD(尽管AccessType.FIELD是默认值。)

现在,如果您在phnnumber字段上没有@Transient,JPA会为您提供3列表:

ID, phnnumber, getphnnumber。 这是因为它会对所有实体字段(id和phnnumber)使用AccessType.FIELD,同时它会为您的getter(getPhnnumber())使用AccessType.PROPERTY。 您将以数据库中两次映射的电话号码结束。

因此,需要@Transient注释 - 这意味着实体不会将字段的值存储在底层存储中,而是存储getter返回的值。

相关问题