java
  • sql
  • hibernate
  • jpa
  • 2016-11-24 23 views 0 likes 
    0

    これは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は正しいですが、それバズーカでフライを撮るような、まったく間違っています...

    +0

    あなたが正しいと言っているSQLは、私が別のJPAプロバイダを使って得たものです。あなたのプロバイダに改善要求を提出する必要があるように見える –

    答えて

    1

    値なしの正しいSQLを生成します。 ちょうどa=?1 を使用してくださいしかし、私はそれも簡単にそれを生成する必要があります期待しています。

    +0

    ありがとう、最も簡単な解決策は、通常、最高です。多くの試みの後、私はこれを試していません。私はあなたと@Neilに同意します。この場合、Hibernateはおそらく正しく動作していません。 – medveshonok117

    関連する問題