5

我在使用 Hibernate 从数据库中获取行时遇到问题。当我只想得到一行时,我收到了 20 行。当我想从大约 1.5k 行的表中获取所有行时,我正好收到 15.2k 行。该表的实体类具有复合主键。

这是我获取所有行的代码:

Criteria criteria = getSession().createCriteria(type);
criteria.setCacheable(true).setCacheRegion(BaseEntity.PACKAGE);
criteria.list();

这是我的实体类:

@javax.persistence.Entity
@Table(name = "my_table")
public class My extends MyEntity<MyPK> {

    @EmbeddedId
    private MyPK id;

    @Column(name = "text", nullable = false)
    protected String text;

    @ManyToOne
    @JoinColumn(name = "property", nullable = false, insertable = false, updatable = false)
    protected Option option;

    @Override
    public MyPK getId() {
        return id;
    }

    @Override
    public void setId(MyPK id) {
        this.id = id;
    }

    //getters and setter
}

这是MyPK类:

@Embeddable
public class MyPK implements Serializable {

   @Column(name = "qwerty")
   protected String qwerty;

   @Column(name = "property")
   protected String property;

   //constructors, getters and setters
}

MyEntity类是带有@MappedSuperclass注释的抽象类。这是这个类头:

@MappedSuperclass
public abstract class MyEntity<T extends Serializable>

我究竟做错了什么?有这个问题EmbeddedId吗?

编辑#1 我已经意识到这是问题所在:

@ManyToOne
@JoinColumn(name = "property", nullable = false, insertable = false, updatable = false)
protected Option option;

此对象包含另一个表的外键。而这个另一个表引用了另一个。最后一张表有 10 行用于上一张表。结果我得到了行数量 * 10。问题可能出在我的实体中的 Hibernate 注释上。

4

4 回答 4

7

看起来您可能正在某个地方急切地加入多对一关系。默认行为是为数据库返回的每一行获取一个实体。如果您不想更改急切获取,但确实想删除结果中的重复项,则需要使用此ResultTransformer

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
于 2012-10-12T22:23:10.790 回答
2

@Embeddable 仅表示MyPK的列将是My类中的列。您的问题可能是 @ManyToOne @JoinColumn(name = "property") 因为它与 MyPK 中的“属性”相同

于 2012-10-09T09:05:53.627 回答
1

您可以通过使用以下方法在条件上设置它来设置结果的最大数量:setMaxResults(int maxResults)

于 2012-10-09T08:54:11.497 回答
1

主键类需要根据聚合值定义 equals() 和 hashCode()(qwerty这里是和property)。很可能在处理 ResultSet 时,Hibernate 不会将多行中的实体键视为相等。

从 JPA 2.0 规范的第 2.4 节(如果有帮助的话):

主键类必须定义 equals 和 hashCode 方法。这些方法的值相等的语义必须与键映射到的数据库类型的数据库相等一致

于 2012-10-09T13:44:22.870 回答