当前位置: 首页 > 知识库问答 >
问题:

由于Hiber警局@公式错误,如何混合JPA和JDBCTemboard

殷烨
2023-03-14

我通过Spring Data JPA使用Hibernate,并尝试添加一个计算字段。一个简单的< code>SELECT 1*1查询可以工作,但是当我添加真正的公式时,Hibernate完全糊涂了,生成了一个语法上无效的查询。

父表:

@Entity
@Table(name = "szallitolevel")
public class Szallitolevel {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Min(1)
    private Long szam;

    @ManyToOne(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @Fetch(FetchMode.JOIN)
    private Partner partner;

    @Formula("(select sum(xx.mennyiseg) from szallitolevel_sor xx where xx.szallitolevel = id)")
//    @Formula("(select 1*1)")
    private Long sumMennyiseg;

    @OneToMany(mappedBy="szallitolevel", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval=true)
    @Fetch(FetchMode.SUBSELECT)
    @Valid
    private List<SzallitolevelSor> sorok = new AutoPopulatingList<SzallitolevelSor>(SzallitolevelSor.class);
}

子表:

@Entity
@Table(name = "szallitolevel_sor")
public class SzallitolevelSor {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    private String nev;

    @Min(0)
    private Long mennyiseg;

    @ManyToOne
    private Szallitolevel szallitolevel;
}

生成的查询中甚至没有sum(),公式不知怎么找到了WHERE部分:

select 
  sorok0_.szallitolevel as szallito4_2_1_, 
  sorok0_.id as id1_3_1_, 
  sorok0_.id as id1_3_0_,
  sorok0_.mennyiseg as mennyise2_3_0_, 
  sorok0_.nev as nev3_3_0_, 
  sorok0_.szallitolevel as szallito4_3_0_ 
from szallitolevel_sor sorok0_ 
where sorok0_.szallitolevel 
  in (select szallitole0_.id 
      from szallitolevel_sor xx 
      where xx.szallitolevel = szallitole0_.id) as formula0_0_,
        partner1_.nev as nev2_1_1_, 
        partner1_.penz as penz3_1_1_ 
from szallitolevel szallitole0_ 
  left outer join partner partner1_ 
    on szallitole0_.partner=partner1_.id) 

 {FAILED after 0 msec}
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as formula0_0_, partner1_.nev as nev2_1_1_, partner1_.penz as penz3_1_1_ from sz' at line 1

更新:我正在使用JDBCTemplate进行相关查询,请参阅答案

共有1个答案

洪博涛
2023-03-14

所以最后我决定尝试保留JPA用于简单的CRUD并允许JDBC逃生路径,如果使某些东西与JPA一起工作需要10分钟以上。使用 JDBC 解决上述问题需要执行以下步骤:

在其中一个配置类中创建 JDBCTemplate bean:

@Bean
public NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) {
    return new NamedParameterJdbcTemplate(dataSource);
}

设置计算实体字段瞬态,以便Hibernate忽略它。还要确保有一个吸气器和一个二传手:

@Entity
@Table(name = "szallitolevel")
public class Szallitolevel {
    ...
    @Transient
    private Long sumMennyiseg = 0L;
    ...
}

自定义 JPA 存储库(您还可以通过提供自定义查询来查找 findAll,在此处查看 Hibernate N 1 问题的修复):

public interface SzallitolevelRepoCustom {
    List<Szallitolevel> customFindAll();
}


public interface SzallitolevelRepo extends CrudRepository<Szallitolevel, Long>, SzallitolevelRepoCustom {
    @Query("select s from Szallitolevel s left join fetch s.partner p")
    List<Szallitolevel> findAll();
}


public class SzallitolevelRepoImpl implements SzallitolevelRepoCustom {
    private static final String FIND_ALL = "SELECT sz.id, sum(sor.mennyiseg) as sumMennyiseg, partner.nev as 'partner.nev' "
            + "from szallitolevel sz "
            + "left join szallitolevel_sor sor on sor.szallitolevel = sz.id "
            + "left join partner on partner.id = sz.partner "
            + "group by sz.id ";

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Override
    public List<Szallitolevel> customFindAll() {
        List<Szallitolevel> result = jdbcTemplate.query(FIND_ALL, new NestedRowMapper<>(Szallitolevel.class));
        return result;
    }
}

请注意别名<code>partner。nev</code>。行映射器将使用它创建一个空的Partner对象,并仅设置nev属性。(如果您需要填充整个对象并且不介意另一个DB查询,您还可以编写一个从Long到Partner的Spring转换器,从数据库中检索整个对象。)

从这里窃取了NestedRowMapper

 类似资料:
  • 但是我在public static void editlist(Collection list1,Collection list2)上得到一个错误,有人能告诉我如何纠正这个错误吗?有人能解释一下什么是java中的Collection*s吗

  • 问题内容: 我在使用Hibernate生成无效SQL时遇到问题。具体来说,混合和匹配隐式和显式联接。这似乎是一个开放的错误。 但是,我不确定 为什么 这是无效的SQL。我想出了一个生成相同语法异常的小型玩具示例。 架构图 数据 工作SQL 这两个查询均有效。我意识到有笛卡尔积;那是故意的。 明确加入: 隐式加入: 无效的SQL 此查询不适用于MSSQL 2000/2008或MySQL: 在MS20

  • 如果提到经常被开发者忽略的特性,那应该就是动态输出错误和提醒的功能了。事实上,Sass 自带三条自定义指令从标准输出系统(CLI,编译程序……)中打印内容: @debug; @warn; @error. 先让我们把 @debug 放一边,毕竟它主要是用作调试 SassScript,而这并不是我们的重点。然后我们就剩下了相互间没有明显差异的 @warn 和 @error,唯一的不同是其中一个可以中断

  • 我试图编译一个MavenJava /Scala混合项目,它有一个Scala类,该类依赖于带有lombok注释的Javabean。我尝试将lombok jar文件添加到Scala编译器的引导类路径以及lombok代理中,但是编译器仍然无法找到生成的getters。Scala编译器是否有办法识别Lombok注释?如果没有,什么是好的解决方案? 请注意,我试图避免引入另一个maven项目,只是为了先编译

  • 问题内容: 在执行SQL脚本文件时,如何获取SQLCMD来仅输出遇到的任何错误或警告? 我基本上不希望基于信息的消息被输出。 问题答案: 通过向其传递参数来防止返回非错误输出消息是不可能的。 但是,您可以做的是将错误消息重定向到,然后将所有其他消息重定向到。 这是通过传递参数来完成的。从在线书籍: -r [0 | 1] msgs到stderr 将错误消息输出重定向到屏幕(stderr)。如果未指定

  • 关于透明度 透明度极其密切地集成在 Illustrator 之中,您很可能在不知不觉间,就在图稿上加了透明度。您可以通过下列任意一种操作在图稿中添加透明度: 降低对象的不透明度,以使底层的图稿变得可见。 使用不透明蒙版来创建不同的透明度。 使用混合模式来更改重叠对象之间颜色的相互影响方式。 应用包含透明度的渐变和网格。 应用包含透明度的效果或图形样式,例如投影。 •导入包含透明度的 Adobe P