Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA Hibernate SqlResultsMapping别名_Java_Postgresql_Hibernate_Jpa_Sqlresultsetmapping - Fatal编程技术网

Java JPA Hibernate SqlResultsMapping别名

Java JPA Hibernate SqlResultsMapping别名,java,postgresql,hibernate,jpa,sqlresultsetmapping,Java,Postgresql,Hibernate,Jpa,Sqlresultsetmapping,在使用JPA2.1和Hibernate 4.3.11实现的Java应用程序中,我尝试使用SqlResultSetMapping将本机查询结果映射到实体。查询包含两个具有相同列名的联接表,所以我需要使用别名并映射它们(此处描述的问题:) 为了简化问题,我将查询和实体缩减到最小,这仍然会导致问题。真正的代码使用两个实体和DB函数,这就是使用本机查询而不是JPQL的原因 网关实体: @Entity public class Gateway implements Serializable { @

在使用JPA2.1和Hibernate 4.3.11实现的Java应用程序中,我尝试使用
SqlResultSetMapping
将本机查询结果映射到实体。查询包含两个具有相同列名的联接表,所以我需要使用别名并映射它们(此处描述的问题:)

为了简化问题,我将查询和实体缩减到最小,这仍然会导致问题。真正的代码使用两个实体和DB函数,这就是使用本机查询而不是JPQL的原因

网关实体:

@Entity
public class Gateway implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private Integer active;
    ...
    @Column(name = "activation_code")
    private String activationCode;
    ...
}
SqlResultsMapping:

@SqlResultSetMapping(
        name = "GatewayWithLoc",
        entities = {
            @EntityResult( entityClass = Gateway.class , fields =     @FieldResult(name = "id", column = "gw_id"))
        }
)
查询:

Query query = em.createNativeQuery("SELECT gw.id AS gw_id, ..., active, activation_code, ... FROM gateway gw", "GatewayWithLoc");
List<Object[]> rows = query.getResultList();
如果我在
SqlResultSetMapping
中使用
SELECT*
而不使用
fields=@FieldResult…
,代码将按预期工作,但由于不同表中的列名相同,我无法这样做

我将通过手动将结果映射到实体来解决这个问题,因为我需要快速的解决方案,但是如果知道我是否做错了什么,或者Hibernate不支持我尝试做的事情,那就太好了。《Pro JPA 2》一书中包含了非常类似的例子,应该是可行的

更新:使用Hibernate 5.1.1(Spring 4.3.2)进行测试-结果相同


更新:看起来所有的列名都需要按照多个答案中提到的那样指定。对我来说,这似乎是JPA/Hibernate的一个大问题——这些列名可以从实体派生,只有手动指定的异常。相反,我需要写3次列名(1.query,2.result set mapping,3.entity),这很难看而且很难维护。

看起来本机查询没有映射到
SqlResultSetMapping
。查询中的列比映射中的列多得多。查询中选定的列必须与映射匹配。

您可以使用
选择新的

  • 创建一个类,该类包含查询中需要使用的所有列

    package dz.immo;
    
    public class GatewayGatewayWithLoc {
        private Integer idGw;
        private Integer activeGw;
        private Integer idGwWl;
        private Integer activeGwWl;
    
            public GatewayGatewayWithLoc(Integer idGw, Integer activeGw, Integer idGwWl, Integer activeGwWl) {
                this.idGw = idGw;
                this.activeGw = activeGw;
                this.idGwWl = idGwWl;
                this.activeGwWl = activeGwWl;
            }
           ....
         // getter and setter
         ...... 
    
        }
    
  • 使用查询

    Query query = em.createQuery("SELECT NEW dz.immo.GatewayGatewayWithLoc(gw.id, gw.active, gwwl.id, gwwl.active) FROM Gateway gw ,GatewayGatewayWithLoc gwwl WHERE ...");
    List<GatewayGatewayWithLoc> liste = query.getResultList();
    // display the answer
    for (GatewayGatewayWithLoc gwgw : liste) {
        System.out.println("GatewayGatewayWithLoc : " + gwgw.getIdGw() + " " + gwgw.getActiveGw()+ " " + gwgw.getIdGwWl()+ " " + gwgw.getActiveGwWl());
    }`
    
    Query Query=em.createQuery(“从网关gw、网关WithLoc gwwl WHERE…)中选择新的dz.immo.GatewayGatewayWithLoc(gw.id、gw.active、gwwl.id、gwwl.active));
    List liste=query.getResultList();
    //显示答案
    用于(带LOC gwgw的网关网关:列表){
    System.out.println(“GatewayGatewayWithLoc:”+gwgw.getIdGw()+“”+gwgw.getActiveGw()+“”+gwgw.getIdGwWl()+“”+gwgw.getActiveGwWl());
    }`
    

  • 我认为您需要显式指定所有的
    @FieldResult
    ,尤其是因为两个表之间的列名冲突。

    看起来是这样的。但是有一些JPA示例(例如,在“Pro JPA 2”一书中)表明这是有效的-只有与实体字段不匹配的列名必须明确指定。我还试图详细说明所有内容,但遇到了不同的问题。更不用说它看起来非常难看-大约50个字段中的每一个都需要指定3次(1.在实体中,2.在查询中,3.在结果集映射中)。看看这里:有这样一句话:“查询需要返回实体的所有属性,JPA实现”我的查询确实返回实体的所有属性。它们只是没有在映射中指定,因为JPA应该能够从实体中确定它们的名称。正如在最初的文章中提到的,如果我在映射中不指定任何字段(仅实体)并且不使用别名,它就可以正常工作。因此,JPA显然能够建立ColumnProperty映射,但一旦在“fields=…”中定义了一个异常,它就会停止使用它。下面是一个假定的工作示例,它使用了与我的代码相同的原则:-如果时间允许,我将在这个主题上做更多的测试。如果这能起作用,那就太好了。您的
    Gateway
    类是否具有本机查询中选择的所有属性?感谢您的回答,选择新外观通常很有用。然而,在我的例子中,我需要在使用自定义DB函数时使用本机查询count()(它进一步使用另一个DB函数的输出作为输入)。我以前对JPA不太满意,因为我对JPQL的lowe表现力感到非常失望(我觉得我经常需要原生查询方式),但现在这。。。太戏剧性了!我必须列出20列,如果其中只有一列发生了变化,我必须在3个地方修复它。这是一场灾难,也是我最初试图用JPA+注释解决的问题。为什么不仅仅依靠秩序呢?名为“id”的第一列对应于具有“id”字段的第一个实体,下一列对应于下一个实体等。