2016-11-24 15 views
0

时,这是我的实体配置休眠/ JPA JPQL错误的SQL查询地图<字符串,字符串>字段

@Entity 
@NamedQuery(name = "Payment.findByEmail", query = "SELECT p FROM Payment p JOIN p.additionalAuthData a " + 
    "WHERE KEY(a) = 'email' AND VALUE(a) = ?1 AND (p.paymentType = 4 OR p.paymentType = 10)") 
public class Payment { 

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

    @Column(name = "payment_type") 
    private Integer paymentType; 

    /** other properties, getters and setters */ 

    @ElementCollection 
    @CollectionTable(name = "additional_auth_data") 
    @MapKeyJoinColumn(name = "id", referencedColumnName = "id") 
    @MapKeyColumn(name = "field") 
    @Column(name = "data_value") 
    private Map<String, String> additionalAuthData; 
} 

的NamedQuery findByEmail( “[email protected]”)生成以下SQL

select -- all fields ... 
from payment payment0_ inner join additional_auth_data additional1_ on payment0_.id=additional1_.id 
where 
    additional1_.field='email' and (select additional1_.data_value from additional_auth_data additional1_ where payment0_.id=additional1_.id)='[email protected]' and (payment0_.payment_type=4 or payment0_.payment_type=10) 

这是错误:它可能工作,如果你有只有一个排,但它否则炸毁。 H2抱怨标量子查询包含多于一行和PostgreSQL 多于一行由作为表达式的子查询返回。事实上,查询的where条件将标量值('[email protected]')与子查询进行比较。

正确的SQL应该是:

select -- all fields 
from payment payment0_ inner join additional_auth_data additional1_ on payment0_.id=additional1_.id 
where additional1_.field='payerEmail' and additional1_.data_value='[email protected]' and (payment0_.payment_type=4 or payment0_.payment_type=10) 

是在HSQL是否正确?有没有办法指示Hibernate生成一个更聪明,更好的SQL?这是一个Hibernate的bug吗?

注:休眠随春引导入门1.3.7.RELEASE

编辑: 使用的@Embeddable类

@ElementCollection 
@JoinTable(name = "additional_auth_data", joinColumns = @JoinColumn(name = "id")) 
@MapKeyColumn(name = "field") 
@Column(name = "data_value") 
private Set<AdditionalData> additionalAuthData; 

@Embeddable 
public static class AdditionalData { 
    @Column(name = "field", nullable = false) 
    private String field; 
    @Column(name = "data_value") 
    private String dataValue; 

    protected AdditionalData() { 
    } 

    public AdditionalData(String field, String dataValue) { 
     this.field = field; 
     this.dataValue = dataValue; 
    } 
    /** Getters, setters; equals and hashCode on "field" */ 
} 


@NamedQuery(name = "Payment.findByEmail", query = "SELECT p FROM Payment p JOIN p.additionalAuthData a " + 
    "WHERE a.field = 'email' AND a.dataValue = ?1 AND (p.paymentType = 4 OR p.paymentType = 10)") 

解决了这个问题,而SQL是正确的,但它看起来只是错误的,就像用火箭筒拍摄一只苍蝇......

+0

您引用的SQL正确的是我使用不同的JPA提供程序。看起来你应该向你的提供商提出改进要求 –

回答

1

它生成正确的SQL没有值()。 只使用a=?1 但我希望是应该生成它也简单与它。

+0

谢谢,最简单的解决方案通常是最好的。经过多次尝试,我没有尝试过这一个。在这种情况下,我同意你和@Neil的说法,Hibernate可能行为不正确。 – medveshonok117

相关问题