【问题标题】:how to force hibernate call setter methods to fill class fields?如何强制休眠调用setter方法来填充类字段?
【发布时间】:2017-08-12 15:52:24
【问题描述】:

我有一个持久类,它有一个临时字段,表示该类的 API 版本(我用于 api 请求的字段的子集)。这个字段是@Transient,因为我简单地使用其他字段来创建它。

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

我试图注释 getter 方法而不是字段以强制休眠使用 setter,但它不起作用

我尝试在字段中使用@Access(AccessType.PROPERTY),但没有成功

如何强制休眠调用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));
    }

【问题讨论】:

标签: java hibernate jpa


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 嘿伙计,你只是复制粘贴了this answer,甚至都不在乎格式化...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
  • 2011-04-09
  • 1970-01-01
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
相关资源
最近更新 更多