java - 如何使用 JPA/Hibernate 延迟实例化属性?

标签 java spring hibernate spring-boot jpa

我一直在使用自定义属性类型和 JPA 的属性转换器。

对于示例 @Entity 类,如下所示:

@Entity
public class ExampleEntity {

    private CustomAttribute customAttribute = new CustomAttribute();

    public CustomAttribute getCustomAttribute() {
        if(this.customAttribute == null){
            this.customAttribute = new CustomAttribute();
        }
        return this.customAttribute;
    }
}

我的CustomAttribute本身有一些属性,我不希望它为空(永远)。我必须在两种选择之间做出选择,并且这两种选择同时得到了证明:

  1. 在属性声明上实例化对象(就像我在字段示例中所做的那样)。
  2. 在 getter 检查 true null 的情况下,为该属性实例化一个新对象。

由于我在生产应用程序上的 @Entity 有超过 10 个属性,因此在所有字段/getter 上应用这些替代方案中的任何一个都太冗长了。

问题:有没有办法在空字段访问时实例化 CustomAttribute 对象?

我在网上的研究中找不到这个具体问题的任何答案,因此我们将不胜感激。

编辑:我的问题不是关于关系映射上字段的延迟实例化,而是关于在访问时实例化自定义属性对象。

最佳答案

有点 hacky 解决方案,您可能更喜欢您自己建议的纯 java 方法:

我创建了一个名为 MyClass 的类,它具有以下构造函数:

@Data // Lombok annotation
public class ExampleEntity {

    @NotNullGetter
    private CustomAttribute customAttribute;

    public ExampleEntity() {

        Class<?> cls = this.getClass();

        for(Field field: cls.getDeclaredFields()) {
            if(field.isAnnotationPresent(NotNullGetter.class)) {
                Class clazz = field.getType();
                try {
                    for(Method method: cls.getDeclaredMethods()) {

                        if(method.getName().startsWith("set") && method.getName().toLowerCase().endsWith(field.getName().toLowerCase())) {
                            // This will create not null object.
                            method.invoke(this, field.getType().newInstance());
                        }
                    }
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

还有我的@NotNullGetter注释

   import java.lang.annotation.*;

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @Documented
    public @interface NotNullGetter {
    }

关于java - 如何使用 JPA/Hibernate 延迟实例化属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57281782/

相关文章:

javascript - 使用 spring 映射 url 填充下拉列表

java - 使用 JPA/Hibernate Criteria 在日期之间拉动

java - 为什么 Hibernate TableSequence 会递减?

java - Hibernate 列变压器

java - 整个应用程序是否有一个 onPause ?

java - 模式版本可以与 jar 文件不同吗?

java - Groovy:一张 map 中元素的更改会影响该 map 副本中的元素

spring - 在spring框架中使用非注释类(bean)可以吗?

java - 有什么方法可以在 Spring 中使用 Swagger 包含 Controller 中未使用的类吗?

java - 浏览器中的系统信息