Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当查询Map字段时,将Hibernate/JPA JPQL转换为错误的SQL_Java_Sql_Hibernate_Jpa - Fatal编程技术网

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)")