Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.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
Spring 由于Hibernate@Formula错误,如何混合使用JPA和JDBCTemplate_Spring_Hibernate_Jpa - Fatal编程技术网

Spring 由于Hibernate@Formula错误,如何混合使用JPA和JDBCTemplate

Spring 由于Hibernate@Formula错误,如何混合使用JPA和JDBCTemplate,spring,hibernate,jpa,Spring,Hibernate,Jpa,我正在通过SpringDataJPA使用Hibernate,并试图添加一个计算字段。一个简单的select1*1查询可以工作,但是当我添加真正的公式时,Hibernate会完全混淆,并生成一个语法无效的查询 父表: @Entity @Table(name = "szallitolevel") public class Szallitolevel { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Lon

我正在通过SpringDataJPA使用Hibernate,并试图添加一个计算字段。一个简单的
select1*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);
}
生成的查询中甚至没有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进行相关查询,请参见答案

,因此最后我决定尝试将JPA保留为简单CRUD,并允许JDBC转义路径(如果使用JPA需要10分钟以上)。使用JDBC解决上述问题需要以下步骤:

在其中一个配置类中创建JDBCTemplatebean:

@Bean
public NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) {
    return new NamedParameterJdbcTemplate(dataSource);
}
将计算实体字段设置为瞬态,以便Hibernate忽略它。还要确保有一个getter和setter:

@Entity
@Table(name = "szallitolevel")
public class Szallitolevel {
    ...
    @Transient
    private Long sumMennyiseg = 0L;
    ...
}
自定义JPA存储库(您还可以通过向
findAll
)提供自定义查询,在这里看到Hibernate N+1问题的修复:

公共接口szallitolevelreposcustom{
列出customFindAll();
}
公共接口SzallitolevelRepo扩展了crudepository、szallitolevelreposcustom{
@查询(“从Szallitolevel s left join fetch s.p中选择s”)
列出findAll();
}
公共类SzallitolevelRepoImpl实现SzallitolevelRepoCustom{
private static final String FIND_ALL=“选择sz.id,sum(sor.mennyiseg)作为sumMennyiseg,partner.nev作为‘partner.nev’”
+“来自szallitolevel sz”
+“在sor.szallitolevel=sz.id上左连接szallitolevel_sor sor”
+“partner.id=sz.partner上的左加入合作伙伴”
+“sz.id集团”;
@自动连线
私有名称参数jdbcTemplate jdbcTemplate;
@凌驾
公共列表customFindAll(){
List result=jdbcTemplate.query(FIND_ALL,newnestedrowmapper(Szallitolevel.class));
返回结果;
}
}
注意SQL中的别名
partner.nev
。行映射器将使用该属性创建一个空的Partner对象,并仅设置
nev
属性。(如果需要填充整个对象并且不介意另一个DB查询,还可以编写一个Spring converter from Long to Partner,从数据库检索整个对象。)


从中偷了
NestedRowMapper

因此,最后我决定尝试将JPA保留为简单CRUD,并允许JDBC转义路径(如果需要10分钟以上才能使用JPA)。使用JDBC解决上述问题需要以下步骤:

在其中一个配置类中创建JDBCTemplatebean:

@Bean
public NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) {
    return new NamedParameterJdbcTemplate(dataSource);
}
将计算实体字段设置为瞬态,以便Hibernate忽略它。还要确保有一个getter和setter:

@Entity
@Table(name = "szallitolevel")
public class Szallitolevel {
    ...
    @Transient
    private Long sumMennyiseg = 0L;
    ...
}
自定义JPA存储库(您还可以通过向
findAll
)提供自定义查询,在这里看到Hibernate N+1问题的修复:

公共接口szallitolevelreposcustom{
列出customFindAll();
}
公共接口SzallitolevelRepo扩展了crudepository、szallitolevelreposcustom{
@查询(“从Szallitolevel s left join fetch s.p中选择s”)
列出findAll();
}
公共类SzallitolevelRepoImpl实现SzallitolevelRepoCustom{
private static final String FIND_ALL=“选择sz.id,sum(sor.mennyiseg)作为sumMennyiseg,partner.nev作为‘partner.nev’”
+“来自szallitolevel sz”
+“在sor.szallitolevel=sz.id上左连接szallitolevel_sor sor”
+“partner.id=sz.partner上的左加入合作伙伴”
+“sz.id集团”;
@自动连线
私有名称参数jdbcTemplate jdbcTemplate;
@凌驾
公共列表customFindAll(){
List result=jdbcTemplate.query(FIND_ALL,newnestedrowmapper(Szallitolevel.class));
返回结果;
}
}
注意SQL中的别名
partner.nev
。行映射器将使用该属性创建一个空的Partner对象,并仅设置
nev
属性。(如果需要填充整个对象并且不介意另一个DB查询,还可以编写一个Spring converter from Long to Partner,从数据库检索整个对象。)


从中偷取了
NestedRowMapper

我试图稍微构造一下SQL。它实际上并不起作用。我似乎试图比它更聪明。嗯,这对我来说是最后一根稻草。在我尝试将JPA应用于实际任务之前,它看起来很有用。在过去的三天里,我解决了一个又一个问题,却没有取得进展。回到JDBCTemplate,我尝试了一下SQL的结构。它实际上并不起作用。我似乎试图比它更聪明。嗯,这对我来说是最后一根稻草。在我尝试将JPA应用于实际任务之前,它看起来很有用。在过去的三天里,我解决了一个又一个问题,却没有取得进展。回到JDBCTemplate。