これはNamedQuery findByEmail( "[email protected]")は、以下のSQLにHibernate/JPA JPQL地図<文字列、文字列>を照会フィールド
を生成@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;
}
私のエンティティの設定です
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のバグですか?
注:Hibernateは春ブーツスターター1.3.7.RELEASE
編集に同梱:
@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)")
は、問題を解決@Embeddableクラスを使用して 、およびSQLは正しいですが、それバズーカでフライを撮るような、まったく間違っています...
あなたが正しいと言っているSQLは、私が別のJPAプロバイダを使って得たものです。あなたのプロバイダに改善要求を提出する必要があるように見える –