【问题标题】:selective columns from multiple tables in one class - Hibernate从一个类中的多个表中选择列 - Hibernate
【发布时间】:2016-09-02 08:10:34
【问题描述】:

我有两个类用户和应用程序。

用户有一对多的映射到应用程序。用户有很多字段,有些是相当大的字段,例如描述。当我想使用它来查看用户和应用程序之间的关系时,我不想加载用户的所有字段,所以我创建了一个具有用户名和应用程序集合的代理类。我如何将这两个表带到这个类?或者最佳实践是什么?

更新:

@Entity
public class UserProfile implements Serializable
{

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long                    id;
    private String                  userName;
    private String                  password;
    @OneToMany
    @JoinTable(name = "userapplicationlink", joinColumns = @JoinColumn(name = "userId"), inverseJoinColumns = @JoinColumn(name = "appId"))
    private Collection<Application> applications; 

}


@Entity
public class Application
{
   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE)
   private int     id;
   private String name;
   private String url;
}

main()
{
    UserProfile user1 = new UserProfile();
    user1.setUserName("sasd");
    user1.setPassword("123");

    Application app = new Application();
    app.setName("User Application");
    app.setPriority(1);
    app.setUrl("/user.do");
    app.setDescription("app");
    user1.setApplications(new ArrayList());
    user1.getApplications().add(app);

    SessionFactory sessionFac = new Configuration().configure().buildSessionFactory();
    Session session = sessionFac.openSession();
    session.beginTransaction();

    session.save(user1);
    session.save(app);

    session.getTransaction().commit();
    System.out.println("End");
    session.close();
    sessionFac.close();


    sessionFac = new Configuration().configure().buildSessionFactory();
    session = sessionFac.openSession();
    session.beginTransaction();
    try
    {
        Query query = session.createQuery("SELECT NEW empire.erp.server.db.UserNameAndApplications(u.userName, u.applications) FROM UserProfile u JOIN FETCH u.applications");
        List result = query.list();
        session.getTransaction().commit();
        session.close();

    }
    finally
    {
        session.close();
        sessionFac.close();
    }
}

堆栈跟踪

线程“main”中的异常 org.hibernate.QueryException:查询指定连接提取,但选择列表中不存在提取关联的所有者 [FromElement{explicit,not a collection join,fetch join,fetch non-惰性属性,classAlias=null,role=empire.erp.server.db.UserProfile.applications,tableName=Application,tableAlias=applicio2_,origin=UserProfile userprofil0_,columns={userprofil0_.id ,className=empire.erp.server.db .Application}}] [SELECT NEW Empire.erp.server.db.UserNameAndApplications(u.userName, u.applications) FROM Empire.erp.server.db.UserProfile u JOIN FETCH u.applications] 在 org.hibernate.QueryException.generateQueryException(QueryException.java:120) 在 org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103) 在 org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:218) 在 org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) 在 org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:115) 在 org.hibernate.engine.query.spi.HQLQueryPlan.(HQLQueryPlan.java:76) 在 org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) 在 org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) 在 org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) 在 org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1907) 在 Empire.erp.server.db.UserProfile.main(UserProfile.java:216) 引起:org.hibernate.QueryException:查询指定连接提取,但选择列表中不存在提取关联的所有者 [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=null ,role=empire.erp.server.db.UserProfile.applications,tableName=Application,tableAlias=application2_,origin=UserProfile userprofil0_,columns={userprofil0_.id ,className=empire.erp.server.db.Application}}] 在 org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:214) 在 org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:991) 在 org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:759) 在 org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:675) 在 org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:311) 在 org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:259) 在 org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:262) 在 org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:190) ... 8 更多

更新 2:运行查询而不获取

休眠:选择 userprofil0_.userName 作为 col_0_0_, 。 as col_1_0_ from UserProfile userprofil0_ inner join userapplicationlink applicatio1_ on userprofil0_.id=applicatio1_.userId inner join Application applicatio2_ on applicatio1_.appId=applicatio2_.id 内部联接 userapplicationlink applicatio3_ on userprofil0_.id=applicatio3_.userId 内部联接 Application applicatio4_ on applicatio3_.appId=应用程序4_.id 2016 年 5 月 7 日下午 4:17:21 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions 警告:SQL 错误:0,SQLState:42601 2016 年 5 月 7 日下午 4:17:21 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions 错误:错误:“。”处或附近的语法错误 位置:43 2016 年 5 月 7 日下午 4:17:21 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl 停止 信息:HHH10001008:清理连接池 [jdbc:postgresql://localhost:5432/optimalyou] 线程“主”org.hibernate.exception.SQLGrammarException 中的异常:无法提取 ResultSet 在 org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106) 在 org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) 在 org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97) 在 org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79) 在 org.hibernate.loader.Loader.getResultSet(Loader.java:2115) 在 org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1898) 在 org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1874) 在 org.hibernate.loader.Loader.doQuery(Loader.java:919) 在 org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) 在 org.hibernate.loader.Loader.doList(Loader.java:2610) 在 org.hibernate.loader.Loader.doList(Loader.java:2593) 在 org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2422) 在 org.hibernate.loader.Loader.list(Loader.java:2417) 在 org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501) 在 org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371) 在 org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216) 在 org.hibernate.internal.SessionImpl.list(SessionImpl.java:1339) 在 org.hibernate.internal.QueryImpl.list(QueryImpl.java:87) 在 Empire.erp.server.db.UserProfile.main(UserProfile.java:217) 引起:org.postgresql.util.PSQLException:错误:“。”或附近的语法错误 位置:43 在 org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2284) 在 org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2003) 在 org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:200) 在 org.postgresql.jdbc.PgStatement.execute(PgStatement.java:424) 在 org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:161) 在 org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:114) 在 org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70) ... 15 更多

【问题讨论】:

  • 你能粘贴你目前尝试过的实体类吗?
  • 参见 19.1.7.docs.jboss.org/hibernate/orm/3.3/reference/en/html/… 优化列读取仅在极端情况下有用。
  • 是的,我知道,这只是一个伪问题。真正的用例是我有两个表,假设有一对多的关系,我会查询大约 10000 条记录。但我对两个表中的所有列都不感兴趣,最多只有两个或三个整数列。

标签: java hibernate jpa


【解决方案1】:

必须为该集合使用别名。不知道为什么。正确的 HQL 是

 SELECT NEW empire.erp.server.db.UserNameAndApplications(u.userName, app) FROM UserProfile u JOIN u.applications app

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    • 2011-03-30
    • 2015-05-03
    相关资源
    最近更新 更多