【问题标题】:Null list returned from hibernate query with embedded id从带有嵌入 id 的休眠查询返回的空列表
【发布时间】:2011-04-27 05:03:39
【问题描述】:

我有一个带有嵌入式密钥的实体。实体只有key作为字段,key有7个字段,部分可以为null。

当我运行以下查询时:

Criteria criteria = session.createCriteria(getPersistentClass());
criteria.add(Restrictions.eq("id.profPropertyId", profileExtensionName));
Object obj = criteria.list();
log.info(obj);
return (List<ProfileExtensions>) obj; 

我得到了正确数量的结果,但每个结果都是空的(即我得到了一个包含 4000 个空对象的列表)。我尝试过同时使用 HQL 查询和条件,但它们都给出了相同的结果。

映射类是从现有数据库生成的。

查询生成的SQL如下

select this_.PROF_DATA_TYPE as PROF1_14_0_, this_.PROF_EXT_KEY as PROF2_14_0_, 
       this_.PROF_KEY as PROF3_14_0_, this_.PROF_NAME as PROF4_14_0_, 
       this_.PROF_PROPERTY_ID as PROF5_14_0_, this_.PROF_VALUE as PROF6_14_0_, 
       this_.PROF_VALUE_EXTENDED as PROF7_14_0_ 
from EMPINST.PROFILE_EXTENSIONS this_ 
where this_.PROF_PROPERTY_ID=?

看起来它应该返回正确的数据。

映射文件非常简单(从架构生成:

// Generated Oct 18, 2010 11:08:08 PM by Hibernate Tools 3.2.2.GA
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name="PROFILE_EXTENSIONS"
    ,schema="EMPINST"
    , uniqueConstraints = @UniqueConstraint(columnNames={"PROF_KEY", "PROF_PROPERTY_ID"}) )
public class ProfileExtensions  implements java.io.Serializable {


 private ProfileExtensionsId id;

public ProfileExtensions() {
}

public ProfileExtensions(ProfileExtensionsId id) {
   this.id = id;
}

 @EmbeddedId

@AttributeOverrides( {
    @AttributeOverride(name="profKey", column=@Column(name="PROF_KEY", nullable=false, length=36) ), 
    @AttributeOverride(name="profPropertyId", column=@Column(name="PROF_PROPERTY_ID", nullable=false, length=64) ), 
    @AttributeOverride(name="profExtKey", column=@Column(name="PROF_EXT_KEY", length=256) ), 
    @AttributeOverride(name="profName", column=@Column(name="PROF_NAME", length=256) ), 
    @AttributeOverride(name="profDataType", column=@Column(name="PROF_DATA_TYPE", length=64) ), 
    @AttributeOverride(name="profValue", column=@Column(name="PROF_VALUE", length=1024) ), 
    @AttributeOverride(name="profValueExtended", column=@Column(name="PROF_VALUE_EXTENDED") ) } )
  public ProfileExtensionsId getId() {
    return this.id;
  }

  public void setId(ProfileExtensionsId id) {
      this.id = id;
  }
}

【问题讨论】:

  • 生成什么SQL?还请显示您的(如果可能,简化)映射和表格。

标签: hibernate hibernate-criteria


【解决方案1】:

一般来说,将可空列作为复合 ID 的一部分可能不是一个好主意。在我的情况下,它是必需的,因为我有一个使用外连接创建的视图,并且我遇到了与您描述的完全相同的问题。我能够使用https://hibernate.atlassian.net/browse/HHH-1109 上提供的信息解决它。我使用了这个 Hibernate Jira 附件中提供的 NullableStringType。在我使用的复合 id 类中:

@Type(type = "nl.pinkroccade.quarant.common.model.hibernate.type.NullableStringType")
private String nullableField;

【讨论】:

【解决方案2】:

我遇到了同样的问题,没有例外,并且空值列表与查询结果的大小相同。我开始评论一些东西并与另一个 EmbeddedId JPA 进行比较。这是我发现的,EmbeddedId 中的所有列都必须为非 null 将 nullable = false 添加到 @AttributeOverride 上的列和 @Embedded id 类中。从 PK 类中删除空列。

我不知道为什么会这样,但确实如此。

【讨论】:

  • 对我来说,使用 Randy P 提出的解决方案,但将可为空的属性添加到 NO PK 类及其 getter 和 setter。
  • 你能举一个兰迪的例子吗?请
【解决方案3】:

您遇到问题是因为您包含了可能具有空值的列。 不要在复合键中包含可为空的列。根据 RDBMS 定义,键不能为空。重新考虑可以唯一标识每一行并使它们成为复合键的一部分的列。

【讨论】:

    【解决方案4】:

    正如 user405935 所说,将可空列作为复合键的一部分并不是一个好主意。

    我的情况与您的情况相同,问题是表中的条目在我的复合键中的列上具有 NULL 值,因此它无法在运行时创建我的嵌入键。

    解决方案:

    1. 使这些列不可为空,或者
    2. 添加一个用作主键的新列,或者
    3. 仅使用不可为空的列查找另一个嵌入键

    【讨论】:

      猜你喜欢
      • 2018-04-20
      • 1970-01-01
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 2015-01-06
      • 1970-01-01
      • 1970-01-01
      • 2017-02-13
      相关资源
      最近更新 更多