【问题标题】:How to retrieve a member object of a class using Hibernate?如何使用 Hibernate 检索类的成员对象?
【发布时间】:2013-11-28 08:51:48
【问题描述】:

使用以下代码,我可以成功检索用户的地址字段,为此我需要使用 Projection 定义其所有字段。想象一下地址有 100 个字段,在这种情况下我必须定义所有字段。

我想知道是否可以只返回客户的地址对象而不在 Proposition 中定义其所有字段?

我知道我可以检索地址的 id 并使用它来检索其对象,但我想知道是否有其他方法而不是 this 或定义其所有字段。

休眠

            .....
            Criteria cre = session.createCriteria(User.class, "user")
                    .createAlias("user.address", "addr");

            cre.add(Restrictions.eq("user.id", ID));

            ProjectionList pl = Projections.projectionList();
            pl.add(Projections.property("addr.id").as("id"));
            pl.add(Projections.property("addr.unit").as("unit"));
            .......
            cre.setProjection(pl);
            Address address = (Address) cre.list().get(0);

我也使用了以下方法,但遇到错误(无法解析属性:地址:com.myProject.User)

    pl.add(Projections.property("addr").as("address"));

Java

@Entity
public Class User {

     @Id
     @GeneratedValue
     private long id;

     @OneToOne
     private Address address;

     ...
}

【问题讨论】:

    标签: java hibernate hibernate-mapping


    【解决方案1】:

    使用 JPQL/HQL:

    select a from User u join u.address a where u.id = :userId
    

    Criteria API 比 JPQL 更受限制,不能选择根实体以外的任何其他实体。如果不必动态组合查询,则不应使用它。当然,如果关联是双向的,你可以简单地使用

    select a from Address a where a.user.id = :userId
    

    或其等效标准:

    Criteria c = session.createCriteria(Address.class, "a");
    c.createAlias("a.user", "u");
    c.add(Restrictions.eq("u.id", userId));
    

    【讨论】:

    • 如果我使用JPQL会不会和hibernate的事务冲突?
    • 请看看我的其他问题谢谢stackoverflow.com/questions/20059700/…
    • 不,当然不是。 JPQL/HQL 是执行 JPA/Hibernate 查询的首选方式。条件对于动态组合查询很有用。
    【解决方案2】:

    如果您从查询中提取的结果将与您定义的 DAO 的字段匹配。我只会对来自 hql 或本机 SQL 查询的结果进行类型转换。

    Select  * 
    From Address a
    where a.id = :userid
    

    Address addrObject = (Address) query.uniqueResult();

    【讨论】:

      【解决方案3】:

      这样做

       Criteria criteria = session.createCriteria(User.class, "user")
                    .createAlias("user.address", "addr")          
                   .add(Restrictions.eq("user.id", userId))            
                   .setProjection(Projections.property("addr"));
      
       Address address = (Address) criteria.list().get(0);
      

      【讨论】:

        【解决方案4】:

        几个选项:

        1. 对地址对象使用lazy="false"。如果由于某种原因必须使用lazy=true,您可以在单独的会话中运行此查询并覆盖该会话中的惰性行为。
        2. 使用特定于数据库的查询获取字段名称列表,然后通过遍历字段名称动态生成 Projections。

        例如, 在mysql中

        SHOW COLUMNS FROM Address
        

        在postgres中

        SELECT * FROM information_schema.columns
        WHERE table_schema = your_schema
        AND table_name   = your_table
        

        我希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 2015-07-10
          • 2015-06-23
          • 1970-01-01
          • 1970-01-01
          • 2019-06-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多