我可以使嵌入式 Hibernate 实体不可为空吗?

发布于 2024-08-02 23:18:47 字数 156 浏览 6 评论 0原文

我想要什么:

@Embedded(nullable = false)
private Direito direito;

但是,正如您所知,@Embeddable 没有这样的属性。

有正确的方法吗?我不想要解决方法。

What I want:

@Embedded(nullable = false)
private Direito direito;

However, as you know there's no such attribute to @Embeddable.

Is there a correct way to do this? I don't want workarounds.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

七月上 2024-08-09 23:18:47

可嵌入组件(或复合元素,无论您如何称呼它们)通常包含多个属性,因此映射到多个列。因此,可以用不同的方式处理整个组件为空的情况; J2EE 规范并不规定一种或另一种方式。

如果组件的所有属性都为 NULL,则 Hibernate 认为该组件为 NULL(反之亦然)。因此,您可以将一个(任何)属性声明为非空(在 @Embeddable 内或作为 @Embedded 上的 @AttributeOverride 的一部分)来实现你想要的。

或者,如果您使用 Hibernate Validator,则可以使用 @NotNull 注释您的属性,尽管这只会导致应用程序级别的检查,而不是数据库级别的检查。

Embeddable components (or composite elements, whatever you want to call them) usually contain more than one property and thus are mapped to more than one column. The entire component being null can therefore be treated in different ways; J2EE spec does not dictate one way or another.

Hibernate considers component to be NULL if all its properties are NULL (and vice versa). You can therefore declare one (any) of the properties to be not null (either within @Embeddable or as part of @AttributeOverride on @Embedded) to achieve what you want.

Alternatively, if you're using Hibernate Validator you can annotate your property with @NotNull although this will only result in app-level check, not db-level.

夜还是长夜 2024-08-09 23:18:47

从 Hibernate 5.1 开始可以使用“hibernate.create_empty_composites.enabled”来更改此行为(请参阅 https: //hibernate.atlassian.net/browse/HHH-7610

It is possible to use "hibernate.create_empty_composites.enabled" since Hibernate 5.1 to change this behavior (see https://hibernate.atlassian.net/browse/HHH-7610 )

黑色毁心梦 2024-08-09 23:18:47

将虚拟字段添加到标记为 @Embeddable 的类中。

@Formula("0")
private int dummy;

请参阅 https://issues.jboss.org/browse/HIBERNATE-50

Add dummy field into class which is marked @Embeddable.

@Formula("0")
private int dummy;

See https://issues.jboss.org/browse/HIBERNATE-50 .

开始看清了 2024-08-09 23:18:47

我对之前提出的任何建议都不太感兴趣,因此我创建了一个方面来为我处理这个问题。

这还没有经过充分测试,并且绝对没有针对嵌入对象的集合进行测试,因此买家要小心。然而,到目前为止似乎对我有用。

基本上,拦截 @Embedded 字段的 getter 并确保填充该字段。

public aspect NonNullEmbedded {

    // define a pointcut for any getter method of a field with @Embedded of type Validity with any name in com.ia.domain package
    pointcut embeddedGetter() : get( @javax.persistence.Embedded * com.company.model..* );


    /**
     * Advice to run before any Embedded getter.
     * Checks if the field is null.  If it is, then it automatically instantiates the Embedded object.
     */
    Object around() : embeddedGetter(){
        Object value = proceed();

        // check if null.  If so, then instantiate the object and assign it to the model.
        // Otherwise just return the value retrieved.
        if( value == null ){
            String fieldName = thisJoinPoint.getSignature().getName();
            Object obj = thisJoinPoint.getThis();

            // check to see if the obj has the field already defined or is null
            try{
                Field field = obj.getClass().getDeclaredField(fieldName);
                Class clazz = field.getType();
                value = clazz.newInstance();
                field.setAccessible(true);
                field.set(obj, value );
            }
            catch( NoSuchFieldException | IllegalAccessException | InstantiationException e){
                e.printStackTrace();
            }
        }

        return value;
    }
}

I wasn't too thrilled with either of the suggestions previously made, so I created an aspect that would handle this for me.

This isn't fully tested, and definitely not tested against Collections of embedded objects, so buyer-beware. However, seems to work for me so far.

Basically, intercepts the getter to the @Embedded field and ensures that the field is populated.

public aspect NonNullEmbedded {

    // define a pointcut for any getter method of a field with @Embedded of type Validity with any name in com.ia.domain package
    pointcut embeddedGetter() : get( @javax.persistence.Embedded * com.company.model..* );


    /**
     * Advice to run before any Embedded getter.
     * Checks if the field is null.  If it is, then it automatically instantiates the Embedded object.
     */
    Object around() : embeddedGetter(){
        Object value = proceed();

        // check if null.  If so, then instantiate the object and assign it to the model.
        // Otherwise just return the value retrieved.
        if( value == null ){
            String fieldName = thisJoinPoint.getSignature().getName();
            Object obj = thisJoinPoint.getThis();

            // check to see if the obj has the field already defined or is null
            try{
                Field field = obj.getClass().getDeclaredField(fieldName);
                Class clazz = field.getType();
                value = clazz.newInstance();
                field.setAccessible(true);
                field.set(obj, value );
            }
            catch( NoSuchFieldException | IllegalAccessException | InstantiationException e){
                e.printStackTrace();
            }
        }

        return value;
    }
}
划一舟意中人 2024-08-09 23:18:47

您可以使用 nullsafe getter。

public Direito getDireito() {
    if (direito == null) {
        direito = new Direito();
    }
    return direito;
}

You can use a nullsafe getter.

public Direito getDireito() {
    if (direito == null) {
        direito = new Direito();
    }
    return direito;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文