【问题标题】:Native query works sqlDeveloper but fails using hibernate本机查询适用于 sqlDeveloper,但使用休眠失败
【发布时间】:2017-08-21 00:53:42
【问题描述】:

我有一个查询,我想使用 hibernate 本机 sqlQuery 运行它

当我使用 sql developer 运行查询时,它工作正常,但是当休眠运行它时,它会抛出此异常

java.sql.SQLException: Invalid column name
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) ~[ojdbc14-10.2.0.4.0.jar:Oracle JDBC Driver version - "10.2.0.4.0"]
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) ~[ojdbc14-10.2.0.4.0.jar:Oracle JDBC Driver version - "10.2.0.4.0"]
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208) ~[ojdbc14-10.2.0.4.0.jar:Oracle JDBC Driver version - "10.2.0.4.0"]
    at oracle.jdbc.driver.OracleStatement.getColumnIndex(OracleStatement.java:3319) ~[ojdbc14-10.2.0.4.0.jar:Oracle JDBC Driver version - "10.2.0.4.0"]
    at oracle.jdbc.driver.OracleResultSetImpl.findColumn(OracleResultSetImpl.java:1926) ~[ojdbc14-10.2.0.4.0.jar:Oracle JDBC Driver version - "10.2.0.4.0"]
    at oracle.jdbc.driver.OracleResultSet.getLong(OracleResultSet.java:1575) ~[ojdbc14-10.2.0.4.0.jar:Oracle JDBC Driver version - "10.2.0.4.0"]
    at org.hibernate.type.descriptor.sql.BigIntTypeDescriptor$2.doExtract(BigIntTypeDescriptor.java:63) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:238) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:234) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:224) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:300) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.loader.Loader.extractKeysFromResultSet(Loader.java:789) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:714) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.loader.Loader.processResultSet(Loader.java:972) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.loader.Loader.doQuery(Loader.java:930) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]

这是来自休眠日志的查询:

Hibernate: select o.GUICHET,count(*) from OPERATIONS o, Guichet g, Centre c where DATE_OPERATIONS between trunc(sysdate,'mm') and add_months(trunc(sysdate,'mm'),1) and c.centre_id=? and c.centre_id=g.centre_id and g.GUICHET_ID=o.GUICHET group by o.GUICHET

这是我的表类定义:

@Entity
@Table(name = "operations")
public class Operations implements Serializable  {

    private static final long serialVersionUID = 1L;

    @GeneratedValue(strategy= GenerationType.AUTO)
    @Id
    private Long operationsId;
    private Date dateOperations;
    @ManyToOne()
    @JoinColumn(name = "guichet", referencedColumnName = "guichetId")
    private Guichet guichet;

编辑:这是我定义这个方法并使用它的代码

@Repository
public interface OperationsRepository extends CrudRepository<Operations, Long> {

    @Query(value="select o.guichet,count(*) from OPERATIONS o, Guichet g, Centre c where DATE_OPERATIONS between trunc(sysdate,'mm') and add_months(trunc(sysdate,'mm'),1) " + 
            "and c.centre_id=?1 and c.centre_id=g.centre_id and g.GUICHET_ID=o.GUICHET " + 
            "group by o.guichet",nativeQuery=true)
    Iterable<Operations> operationsStat( Long centreId);

使用这个方法:

@Override
    public Iterable<Operations> operationsStat(Long centreId) {
        return operationsRepository.operationsStat(centreId);
    }


@GetMapping(value="/statistique")
    @ResponseBody()
    Iterable<Operations> doStatistique()
    {
        return operationsServiceImpl.operationsStat(new Long(selectedCentre)); 
    }

【问题讨论】:

  • java.sql.SQLException: Invalid column name 表示您的查询工作正常,但您的结果集没有获取列名,因为查询中不存在该列名。也许错误来自您尝试读取来自自定义查询的值的代码部分。您能否提供您读取来自查询的值的那部分?
  • 在此之前,如果我在 select 和 group by 中提供其余的表列名称,查询将起作用并返回结果,但我没有得到我想要的结果。
  • 我只是简单地将这个可迭代的方法返回给 ajax 调用,这样我就可以循环抛出它。在 java 中不访问其中的任何值
  • 好的,同时查看堆栈跟踪也有oracle.jdbc.driver.OracleResultSet.getLong,这意味着您正在尝试读取一个长值,但我无法在发生读取操作的代码中。跨度>
  • 查看我添加代码的编辑

标签: java sql spring hibernate oracle-sqldeveloper


【解决方案1】:

更改返回类型后的代码:

@Repository
public interface OperationsRepository extends CrudRepository<Operations, Long> {

    @Query(value="select o.guichet,count(*) from OPERATIONS o, Guichet g, Centre c where DATE_OPERATIONS between trunc(sysdate,'mm') and add_months(trunc(sysdate,'mm'),1) " + 
            "and c.centre_id=?1 and c.centre_id=g.centre_id and g.GUICHET_ID=o.GUICHET " + 
            "group by o.guichet",nativeQuery=true)
    Iterable<Object> operationsStat( Long centreId);

然后这个:

@Override
    public Iterable<Object> operationsStat(Long centreId) {
        return operationsRepository.operationsStat(centreId);
    }


@GetMapping(value="/statistique")
    @ResponseBody()
    Iterable<Object> doStatistique()
    {
        return operationsServiceImpl.operationsStat(new Long(selectedCentre)); 
    }

【讨论】:

    【解决方案2】:

    Operations 类中有一个字段

    private Date dateOperations;
    

    但是查询没有为该字段返回任何值。

    也一样
    private Guichet guichet;
    

    查询中没有列 guichetId,并且您的 count(*) 在类中没有映射字段。

    【讨论】:

    • 我不想为每个 guichet (guichet_id) 的所有行数感兴趣的这两个字段返回一个值
    【解决方案3】:

    似乎@Query(value="select o.guichet,count(*) from OPERATIONS o .. 正在返回Guichet 对象的列表,但您期待的是List&lt;Operations&gt;

    一种选择是为您的操作静态创建一个外部 pojo(例如使用包名称:com.myorg.model)

    package com.myorg.model;
     public class OperationsStas {
      private Guichet guichet;
      private Long   count;
    
      public OperationsStas(Guichet guichet, Long count) {
        this.guichet = guichet;
        this.count  = count;
      }
    

    }

    回购可能是这样的:

    @Repository
    public interface OperationsRepository extends CrudRepository<Operations, Long> {
    
        @Query(value="select new com.myorg.model.com.myorg.model.OperationsStats(o.guichet,count(*)) from OPERATIONS o, Guichet g, Centre c where DATE_OPERATIONS between trunc(sysdate,'mm') and add_months(trunc(sysdate,'mm'),1) " + 
                "and c.centre_id=?1 and c.centre_id=g.centre_id and g.GUICHET_ID=o.GUICHET " + 
                "group by o.guichet",nativeQuery=true)
        List<OperationsStas> operationsStat( Long centreId);
    

    而且控制也必须改变

    @Override
        public List<OperationsStas> operationsStat(Long centreId) {
            return operationsRepository.operationsStat(centreId);
        }
    
    
    @GetMapping(value="/statistique")
        @ResponseBody()
        List<OperationsStas> doStatistique()
        {
            return operationsServiceImpl.operationsStat(new Long(selectedCentre)); 
        }
    

    希望对你有帮助。

    【讨论】:

    • 感谢您让我注意到返回类型我很盲目,我只需将其更改为对象并让编译器完成它的工作,现在它可以工作了
    • 是的,对象返回类型也是一种选择。如果你愿意,你可以发布你的替代方案,这样可以帮助其他有类似问题的人。
    猜你喜欢
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 2012-03-29
    • 1970-01-01
    相关资源
    最近更新 更多