无法在休眠中提取ResultSet


78

我对Hibernate有问题。我尝试解析为List,但抛出异常:HTTP Status 500 - could not extract ResultSet。当我调试时,它在线路上query.list()出错...

我的示例代码在这里

@Entity
@Table(name = "catalog")
public class Catalog implements Serializable {

@Id
@Column(name="ID_CATALOG")
@GeneratedValue 
private Integer idCatalog;

@Column(name="Catalog_Name")
private String catalogName;

@OneToMany(mappedBy="catalog", fetch = FetchType.LAZY)
private Set<Product> products = new HashSet<Product>(0);

//getter & setter & constructor
//...
}


@Entity
@Table(name = "product")
public class Product implements Serializable {

@Id
@Column(name="id_product")
@GeneratedValue 
private Integer idProduct;

@ManyToOne
@JoinColumn(name="ID_CATALOG")
private Catalog catalog;

@Column(name="product_name")
private String productName;

@Column(name="date")
private Date date;

@Column(name="author")
private String author;

@Column(name="price")
private Integer price;

@Column(name="linkimage")
private String linkimage;

//getter & setter & constructor
}



@Repository
@SuppressWarnings({"unchecked", "rawtypes"})
public class ProductDAOImpl implements ProductDAO {
    @Autowired
    private SessionFactory sessionFactory;
public List<Product> searchProductByCatalog(String catalogid, String keyword) {
    String sql = "select p from Product p where 1 = 1";
    Session session = sessionFactory.getCurrentSession();

    if (keyword.trim().equals("") == false) {
        sql += " and p.productName like '%" + keyword + "%'";
    }
    if (catalogid.trim().equals("-1") == false
            && catalogid.trim().equals("") == false) {
        sql += " and p.catalog.idCatalog = " + Integer.parseInt(catalogid);
    }
    Query query = session.createQuery(sql);
    List listProduct = query.list();
    return listProduct;
}

}

我的豆子

  <!-- Scan classpath for annotations (eg: @Service, @Repository etc) -->
  <context:component-scan base-package="com.shopmvc"/>

  <!-- JDBC Data Source. It is assumed you have MySQL running on localhost port 3306 with 
       username root and blank password. Change below if it's not the case -->
  <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/shoesshopdb?autoReconnect=true"/>
    <property name="username" value="root"/>
    <property name="password" value="12345"/>
    <property name="validationQuery" value="SELECT 1"/>
  </bean>

  <!-- Hibernate Session Factory -->
  <bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>
    <property name="packagesToScan">
      <array>
        <value>com.shopmvc.pojo</value>
      </array>
    </property>
    <property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.MySQLDialect
      </value>
    </property>
  </bean>

  <!-- Hibernate Transaction Manager -->
  <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory"/>
  </bean>

  <!-- Activates annotation based transaction management -->
  <tx:annotation-driven transaction-manager="transactionManager"/>

例外:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:948)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

root cause 

org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:82)
    org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:61)
    org.hibernate.loader.Loader.getResultSet(Loader.java:2036)

root cause 

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'product0_.ID_CATALOG' in 'field list'
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    java.lang.reflect.Constructor.newInstance(Unknown Source)
    com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
    com.mysql.jdbc.Util.getInstance(Util.java:386)
    com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054)
    com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
    com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
    com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
    com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
    com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
    com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
    com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2322)
    org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
    org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
    org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:56)
    org.hibernate.loader.Loader.getResultSet(Loader.java:2036)
    org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1836)
    org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1815)
    org.hibernate.loader.Loader.doQuery(Loader.java:899)
    org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
    org.hibernate.loader.Loader.doList(Loader.java:2522)
    org.hibernate.loader.Loader.doList(Loader.java:2508)
    org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2338)
    org.hibernate.loader.Loader.list(Loader.java:2333)
    org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:490)

我的数据库:

CREATE TABLE `catalog` (
  `ID_CATALOG` int(11) NOT NULL AUTO_INCREMENT,
  `Catalog_Name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`ID_CATALOG`)
)

CREATE TABLE `product` (
  `id_product` int(11) NOT NULL AUTO_INCREMENT,
  `product_name` varchar(45) DEFAULT NULL,
  `date` date DEFAULT NULL,
  `author` varchar(45) DEFAULT NULL,
  `price` int(11) DEFAULT NULL,
  `catalog_id` int(11) DEFAULT NULL,
  `linkimage` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id_product`),
  KEY `FK_Product_idx` (`catalog_id`),
  CONSTRAINT `FK_Product` FOREIGN KEY (`catalog_id`) REFERENCES `catalog` (`ID_CATALOG`) ON DELETE NO ACTION ON UPDATE NO ACTION
)

Answers:


75

@JoinColumn批注指定列的名称被用作对目标实体的外键。

Product上面的类上,连接列的名称设置为ID_CATALOG

@ManyToOne
@JoinColumn(name="ID_CATALOG")
private Catalog catalog;

但是,外键上的 Product表称为catalog_id

`catalog_id` int(11) DEFAULT NULL,

您需要更改表上的列名或您在中使用的名称,以@JoinColumn使它们匹配。参见http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-association


26

对于其他人遇到的同一错误消息,另一个潜在的原因是,如果您访问的表与经过身份验证的表不同,则将发生此错误。

在这种情况下,您需要将架构名称添加到您的实体条目中:

@Table(name= "catalog", schema = "targetSchemaName")

它是在我尝试创建新的sboot -mysql -jpa应用程序时发生的。没有创建数据库表。这解决了我的问题。
Suraj Patil

或表名称不匹配......@Table(name = "catalog", schema = "taretSchemaName")且表名称为时taretSchemaName
保罗

6

尝试在查询中使用内部联接

    Query query=session.createQuery("from Product as p INNER JOIN p.catalog as c 
    WHERE c.idCatalog= :id and p.productName like :XXX");
    query.setParameter("id", 7);
    query.setParameter("xxx", "%"+abc+"%");
    List list = query.list();

在休眠配置文件中也有

<!--hibernate.cfg.xml -->
<property name="show_sql">true</property>

在控制台上显示正在查询的内容。


4

我有类似的问题。尝试使用HQL编辑器。它将显示SQL(因为您有SQL语法例外)。复制您的SQL并分别执行。就我而言,问题出在架构定义中。我定义了架构,但是我应该将其保留为空。这引发了与您相同的异常。错误描述反映了实际状态,因为模式名称已包含在SQL语句中。


4

如果没有在数据库中创建“ HIBERNATE_SEQUENCE”序列(如果使用oracle或任何基于序列的数据库),则将得到相同类型的错误;

确保那里有序列;


5
你能详细说明吗?
samisnotinsane

如果您正在使用oracle DB并禁用了自动模式创建,那么您可能也缺少该顺序HIBERNATE_SEQUENCE。如果是这种情况,您可以尝试将生成的值批注更改为其他内容,例如:@GeneratedValue(strategy=GenerationType.IDENTITY)如果您使用列上的标识生成作为id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
办公场所

4

我在application.properties文件中使用了以下属性,此问题已解决

spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

之前遇到错误

There was an unexpected error (type=Internal Server Error, status=500).
could not extract ResultSet; SQL [n/a]; nested exception is 
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:280)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:254)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

我猜这是(有时更好)替代上面建议的@Table(name =“ catalog”,schema =“ targetSchemaName”)的替代方法。更好,因为当您从EE应用程序中复制代码时,您不必修改实体类。
user2081279

4

当我尝试更新一行时,我遇到了同样的问题:

@Query(value = "UPDATE data SET value = 'asdf'", nativeQuery = true)
void setValue();

我的问题是我忘记添加@Modifying注释:

@Modifying    
@Query(value = "UPDATE data SET value = 'asdf'", nativeQuery = true)
void setValue();

2

将数据库从在线服务器迁移到本地主机后,我遇到了同样的问题。模式已更改,因此我必须为每个表手动定义模式:

@Entity
@Table(name = "ESBCORE_DOMAIN", schema = "SYS")

0

另一个解决方案是添加@JsonIgnore:

@OneToMany(mappedBy="catalog", fetch = FetchType.LAZY)
@JsonIgnore
private Set<Product> products = new HashSet<Product>(0);

11
解释这将如何解决伙伴问题。寻求答案的人将通过了解解决方案而受益匪浅。
Rai

0

我正在将Spring Data JPA与PostgreSql一起使用,并且在UPDATE调用期间它显示了错误-

  • '无法提取ResultSet '和另一个。
  • org.springframework.dao.InvalidDataAccessApiUsageException:执行更新/删除查询;嵌套的异常是javax.persistence.TransactionRequiredException:执行更新/删除查询。(显示需要交易。

实际上,我缺少两个必需的注释。

  • @交易和
  • @修改

与-

@Query(vlaue = " UPDATE DB.TABLE SET Col1 = ?1 WHERE id = ?2 ", nativeQuery = true)
void updateCol1(String value, long id);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.