Java 当查询Map字段时,将Hibernate/JPA JPQL转换为错误的SQL
这是我的实体配置Java 当查询Map字段时,将Hibernate/JPA JPQL转换为错误的SQL,java,sql,hibernate,jpa,Java,Sql,Hibernate,Jpa,这是我的实体配置 @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
@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;
}
这是错误的:如果你只有一排,它可能会工作,但它会爆炸,否则。H2抱怨标量子查询包含多行,PostgreSQL抱怨子查询作为表达式返回的多行。实际上,查询的where条件比较标量值的test@example.com'的子查询
正确的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='test@example.com' and (payment0_.payment_type=4 or payment0_.payment_type=10)
HSQL正确吗?有没有一种方法可以指导Hibernate生成一个聪明、更好的SQL?这是冬眠虫吗
注意:Hibernate随Spring Boot Starter 1.3.7.0版本一起提供
编辑:
使用@Embeddeble类
@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而没有价值。 只使用a=?1
但我希望它也能简单地生成。它生成正确的SQL而没有价值。 只使用a=?1
但我希望它也能简单地生成。您引用的正确SQL是我使用另一个JPA提供程序得到的。看起来您应该对您的提供者提出改进请求您引用的SQL是正确的,这是我使用其他JPA提供者得到的。看起来您应该向供应商提出改进请求谢谢,最简单的解决方案通常是最好的。经过多次尝试,我还没有试过这个。我同意你和@Neil的观点,在这种情况下,Hibernate可能表现不正确。谢谢,最简单的解决方案通常是最好的。经过多次尝试,我还没有试过这个。我同意你和@Neil的观点,在这种情况下,Hibernate可能行为不正确。
@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)")