ORA-00918:“列模糊定义”

时间:2014-06-23 11:36:59

标签: java sql oracle hibernate jpa

我一直试图理解为什么Oracle会在几天内提出这个错误,但是找不到任何帮助我阅读所有相关主题的解决方案。我希望有人会帮助我。 我正在处理这个问题:

SELECT distinct c.NAME, c.SUPERVISIONNAME, c.INTERNALADDRESS, c.IM, c.ID, c.LINK, c.IW, d.NAME, t.NAME
FROM "CONCENTRATOR" c
LEFT OUTER JOIN "CONCENTRATOR_GROUP" USING(CONCENTRATOR_ID)
LEFT OUTER JOIN "GROUP" g USING(GROUP_ID)
LEFT OUTER JOIN "TYPE" t USING(TYPE_ID)
LEFT OUTER JOIN "DEPARTMENT" d USING(DEPARTMENT_ID)
WHERE TRIM(UPPER(t.NAME)) = 'type'
ORDER BY im DESC, id DESC, link DESC, iw DESC, TRIM(UPPER(d.name)) ASC, TRIM(UPPER(c.name)) ASC;

这在SQL Developer上完全正常,但在Java中运行时会引发此错误:

java.sql.SQLSyntaxErrorException: ORA-00918: column ambiguously defined

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:879)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:884)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1167)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1289)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3628)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1493)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at sun.reflect.GeneratedMethodAccessor29.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at com.sun.proxy.$Proxy39.executeQuery(Unknown Source)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1978)
at org.hibernate.loader.Loader.doQuery(Loader.java:829)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
at org.hibernate.loader.Loader.doList(Loader.java:2463)
at org.hibernate.loader.Loader.doList(Loader.java:2449)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2279)
at org.hibernate.loader.Loader.list(Loader.java:2274)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:331)
at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1585)
at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:224)
at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:156)
at com.francetelecom.visionet.server.persistance.dao.impl.TemplateDAOImpl.paginate(TemplateDAOImpl.java:282)
at com.francetelecom.visionet.server.persistance.dao.impl.ConcentratorDAOImpl.findByCriteriaTest(ConcentratorDAOImpl.java:545)

由我的程序中的这一行引起(其中querySelect是相关的SQLQuery对象):

List<T> list = (List<T>) querySelect.addEntity(referenceClass).list();

由于ORDER BY,我需要在SELECT中保留c.NAME,d.NAME和t.NAME,并且我不知道如何在不引发此错误的情况下执行此操作...我尝试了别名选择,但也没有工作。

修改

似乎是一个Hibernate问题,而不仅仅是SQL问题。 这是在&#34; addEntity&#34;上提出错误的函数。线。在这种情况下,预计会返回一个集中器对象列表。

@Override
@SuppressWarnings("unchecked")
public PaginatedList<T> paginate(SQLQuery querySelect, SQLQuery queryCount, int page, int numPerPage) throws PersistanceException
{
    PaginatedList<T> pList = new PaginatedList<T>();
    try {
        int offset = 0;
        if (numPerPage > -1) {
            offset = page * numPerPage;
        }
        int totalAllPages = ((BigDecimal) queryCount.uniqueResult()).intValue();
        querySelect.setMaxResults(numPerPage);
        querySelect.setFirstResult(offset);
        List<T> listAll = (List<T>) querySelect.addEntity(referenceClass).list();
        pList.setItems(listAll);
        pList.setPage(page);
        pList.setPageSize(numPerPage);
        pList.setTotal(totalAllPages);
    } catch (HibernateException e) {
        throw new PersistanceException(e);
    }
    return pList;
}

以下是集中器的对象字段:

private String name;
private String supervisionName;
private String internalAddress;
private boolean activeAlarms;
private int im;
private int id;
private int iw;
private int link;
private Date lastUpdate;
private Type type;
private Department department;

5 个答案:

答案 0 :(得分:2)

我终于找到了解决方案,感谢大家! 我接受了JoãoMendes的回答,因为我实际上用正确的别名解决了这个问题,但所有其他答案都是相关的,并帮助了我。

这是最终查询。 在DISTINCT中,我将所有映射对象的(集中器)字段加上ORDER BY中使用的两个字段使用了正确的别名。 我觉得不是最漂亮的,但工作得很好!

SELECT DISTINCT CONCENTRATOR_ID, c.NAME, SUPERVISIONNAME, INTERNALADDRESS, ACTIVEALARMS, IM, ID, LINK, IW, LASTUPDATE, TYPE_ID, DEPARTMENT_ID, d.NAME as "department.name", t.NAME as "type.name"
FROM "CONCENTRATOR" c LEFT OUTER JOIN "CONCENTRATOR_GROUP" USING(CONCENTRATOR_ID)
LEFT OUTER JOIN "GROUP" g USING(GROUP_ID)
LEFT OUTER JOIN "TYPE" t USING(TYPE_ID)
LEFT OUTER JOIN "DEPARTMENT" d USING(DEPARTMENT_ID)
WHERE (g.ident = 1) OR (g.ident = 16) OR (g.ident = 44)
AND (c.iw) > 0
AND TRIM(UPPER(t.name)) = 'OTELO'
ORDER BY im DESC, id DESC, link DESC, iw DESC, TRIM(UPPER(d.name)) ASC, TRIM(UPPER(c.name)) ASC 

答案 1 :(得分:1)

我认为这可能对你有用..

将完全限定名称用于 order by 子句中的所有列。

SELECT distinct c.NAME, c.SUPERVISIONNAME, c.INTERNALADDRESS, c.IM, c.ID, c.LINK, c.IW, d.NAME, t.NAME
FROM "CONCENTRATOR" c
LEFT OUTER JOIN "CONCENTRATOR_GROUP" USING(CONCENTRATOR_ID)
LEFT OUTER JOIN "GROUP" g USING(GROUP_ID)
LEFT OUTER JOIN "TYPE" t USING(TYPE_ID)
LEFT OUTER JOIN "DEPARTMENT" d USING(DEPARTMENT_ID)
AND TRIM(UPPER(t.NAME)) = 'type'
ORDER BY c.IM DESC, c.ID DESC, c.LINK DESC, c.IW DESC, TRIM(UPPER(d.name)) ASC, TRIM(UPPER(c.name)) ASC;

答案 2 :(得分:1)

尝试使用以下查询,您有三个name列,我已将其重命名为fnamesnametname。尽可能使用独特的名称重命名他们想要的那些。

另请注意,您已经使用了一些保留关键字,因此请尝试使用别名,但我已将其重命名。最好避免在创建数据库对象时使用保留关键字以避免错误。

SELECT DISTINCT c.NAME FNAME,
                  c.SUPERVISIONNAME SUPERVISIONNAME,
                  c.INTERNALADDRESS INTERNALADDRESS,
                  c.IM IM,
                  c.ID T_ID,
                  c.LINK T_LINK,
                  c.IW T_IW,
                  d.NAME SNAME,
                  t.NAME TNAME
    FROM CONCENTRATOR c
         LEFT OUTER JOIN CONCENTRATOR_GROUP
            USING (CONCENTRATOR_ID)
         LEFT OUTER JOIN GROUP g
            USING (GROUP_ID)
         LEFT OUTER JOIN TYPE t
            USING (TYPE_ID)
         LEFT OUTER JOIN DEPARTMENT d
            USING (DEPARTMENT_ID)
   WHERE TRIM (UPPER (t.NAME)) = 'type'
ORDER BY im DESC,
         T_ID DESC,
         T_LINK DESC,
         T_IW DESC,
         TRIM (UPPER (SNAME)) ASC,
         TRIM (UPPER (FNAME)) ASC;

答案 3 :(得分:1)

这看起来像是一个Hibernate,而不是严格的SQL问题。

我认为addEntity要求所有列都有不同的名称,这些名称与要添加的实体中的字段相匹配。 Oracle,唉,返回带有重复问题名称的结果没有问题,这就是为什么你的查询在SQL Developer中工作的原因。

尝试为SELECT子句中的所有列提供不同的别名,特别是与实体中的字段成员匹配的别名。

答案 4 :(得分:1)

Hibernate可能会将SQL包装在另一个查询中,以便使用Oracle的rownum过滤maxresults和firstrows。这意味着任何重复项(c.Name和d.NAME)都会导致异常,除非如此处所述出现别名:Column ambiguously defined in subquery using rownums

其他JPA提供程序(例如EclipseLink)会在使用分页时自动为字段设置别名,因此您可能需要检查以后的Hibernate版本是否执行相同操作或拉出此处所述的修补程序https://hibernate.atlassian.net/browse/HHH-951另一个重复的错误描述了问题是https://hibernate.atlassian.net/browse/HHH-1436