【问题标题】:Setting up query for specific field of Hibernate entity为 Hibernate 实体的特定字段设置查询
【发布时间】:2015-12-08 18:27:09
【问题描述】:

我使用弹簧和休眠。出现了以下情况,不知道是否真的可以实现。将不胜感激。

比如有个hibernate实体

    @Entity
public class TestEntity {
    private String field1;
    private String field2;
    private String specField;

    @Column(name = "field1")
    public String getField1() {
        return field1;
    }

    @Column(name = "field2")
    public String getField2() {
        return field2;
    }

    public String getSpecField() {
        return (field1 != null ? field1 : field2);
    }
}

我需要通过 SQL 查询而不是 java 代码生成 specField 的值。 像这样的

    @Entity
public class TestEntity {
    private String field1;
    private String field2;
    private String specField;

    @Column(name = "field1")
    public String getField1() {
        return field1;
    }

    @Column(name = "field2")
    public String getField2() {
        return field2;
    }

    @Query(value= "COALESCE(field1, field2)")
    public String getSpecField() {
        return specField;
    }
}

有人告诉我应该有能力这样做。但没有找到任何批准这一点的东西。

查询究竟做了什么实际上并不重要。我需要那个 specField 将被一些查询而不是 java 代码。有可能吗?

感谢您的帮助。

更新感谢@premkumar,建议使用@Formula 所以现在我有

@Entity
public class TestEntity {
    private String field1;
    private String field2;
    private String specField;

    @Column(name = "field1")
    public String getField1() {
        return field1;
    }

    @Column(name = "field2")
    public String getField2() {
        return field2;
    }

    @Formula("COALESCE(field2, field2)")
    public String getSpecField() {
        return (field1 != null ? field1 : field2);
    }
}

但应用程序无法在 bean 初始化时启动 org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory 处的 NullPointerException

我还尝试了以下方法:

  1. 将公式放在“私有字符串 specField”之上 - 应用已启动,但休眠失败,因为无法在数据库中找到 spec_field

  2. 将 @Formula 和 @Transient 放在 getter 上 - 应用程序已启动,没有错误,但 specField 始终为空。看起来hibernate完全忽略了它

【问题讨论】:

  • 为什么不使用@PrePersist 或@PreUpdate 为该实体设置字段中的值?
  • 你的意思是 specField 应该有值(field1 + ", "+ field2)吗?如果不是你能更清楚
  • @RossiRobinsion 我实际上并不知道。我现在研究一下
  • @premkumar specField 应该是 field1 如果 field2 为 null 或 field2 如果 field1 为 null
  • 这些是回调方法。例如:javabeat.net/jpa-entity-listeners-callback-methods

标签: java mysql spring hibernate


【解决方案1】:

如果您使用的是休眠,请尝试以下操作:

@Formula("COALESCE(field1, field2)")
public String getSpecField() {
    return specField;
}

注意:- 据我所知,JPA 中没有其他选择。注意这会混淆 hibernate 和 jpa 注释。

【讨论】:

  • 谢谢!这完全符合我的需求。但是以某种方式添加此注释会破坏项目,并且它不会以 org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory 处的 NullPointerException 开始。也许你有想法这可能是什么?
  • @me1111 这对你有用吗?如果是,那么此异常何时发生?删除注释时会发生什么情况?你仍然得到异常吗?
  • bean 初始化失败,堆栈跟踪导致 LocalSessionFactoryBean.newSessionFactory 中出现 NullPointerException。删除注释后,应用程序启动正常,但在获取时休眠失败并显示“数据库中没有规范字段列”。我用详细信息更新了我的帖子
  • 不要混淆字段和getter注释..遵循一种风格..在你的情况下保持它在getter上以保持一致性..删除瞬态注释,因为hibernate将完全忽略该元素......你能提供完整的堆栈吗追踪
  • 似乎与休眠版本有关。 stackoverflow.com/questions/3331529/…你用的是哪个版本?
【解决方案2】:

为什么不:

public String getSpecField() {
   return MoreObjects.firstNonNull(field1,field2);
}

【讨论】:

  • 通过SQL查询而不是java代码生成specField很重要
  • JPA 2.0 API 支持 Coalesce。尝试从 TestEntity 中选择 COALESCE(field1,field2) 作为 specField
  • 不确定我是否正确。你的意思是我可以把它作为完整实体的@NativeQuery?
  • 看看休眠中的@SqlResultSetMapping,它允许您将对象的字段映射到本机查询检索到的列
【解决方案3】:

您可以利用 JPA 回调方法:

  1. 创建一个实体监听器:

    public class MyEntityListener {
    
        @PrePersist
        @PreUpdate
        public void prePersist(Object object) {
            if(object instanceOf TestEntity ) {
                object.specField  = object.field1 != null ? object.field1 : object.field2
            }
        }
    }
    
  2. 用@EntityListener 注释你的类:

    @Entity
    @EntityListeners(MyEntityListener .class)
    public class TestEntity {
        private String field1;
        private String field2;
        private String specField;
    
        //default cons - getters and setters
    }
    

【讨论】:

  • 通过SQL查询而不是java代码生成specField很重要
  • 您需要详细说明您对 SQL Query 生成的定义。
  • 我的意思是hibernate应该通过执行SQL来获取specField的值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 2020-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多