时,这是我的实体配置休眠/ 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是正确的,但它看起来只是错误的,就像用火箭筒拍摄一只苍蝇......
您引用的SQL正确的是我使用不同的JPA提供程序。看起来你应该向你的提供商提出改进要求 –