최대 절전 모드에서 ResultSet을 추출 할 수 없습니다.


80

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
)

답변:


76

@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를


27

다른 사람들이 동일한 오류 메시지를 보게되는 또 다른 잠재적 원인은 인증 한 스키마와 다른 스키마의 테이블에 액세스하는 경우이 오류가 발생하기 때문입니다.

이 경우 엔티티 항목에 스키마 이름을 추가해야합니다.

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

내 경우에는 새로운 sboot -mysql -jpa 앱을 만들려고 할 때 발생했습니다. db 테이블이 생성되지 않았습니다. 이것은 내 문제를 해결했습니다.
Suraj Patil

또는 테이블 이름이 일치하지 않을 때 ... like @Table(name = "catalog", schema = "taretSchemaName")및 테이블 이름은 taretSchemaName.
Paolo

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>

콘솔에 쿼리중인 내용을 표시합니다.


5

행을 업데이트하려고 할 때 동일한 문제가 발생했습니다.

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

내 문제는 @Modifying주석 을 추가하는 것을 잊었다는 것입니다 .

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

4

비슷한 문제가있었습니다. HQL 편집기를 사용해보십시오. SQL을 표시합니다 (SQL 문법 예외가 있으므로). SQL을 복사하고 별도로 실행하십시오. 제 경우에는 스키마 정의에 문제가있었습니다. 스키마를 정의했지만 비워 두어야합니다. 이것은 당신이 얻은 것과 같은 예외를 발생시킵니다. 그리고 SQL 문에 스키마 이름이 포함되어 있으므로 오류 설명은 실제 상태를 반영합니다.


4

데이터베이스에 'HIBERNATE_SEQUENCE'시퀀스가 생성되지 않은 경우 (오라클 또는 시퀀스 기반 데이터베이스를 사용하는 경우) 동일한 유형의 오류가 발생합니다.

시퀀스가 거기에 있는지 확인하십시오.


5
자세히 설명해 주시겠습니까?
samisnotinsane

oracle DB를 사용 중이고 자동 스키마 생성을 비활성화 한 경우 시퀀스 HIBERNATE_SEQUENCE도 누락되었을 수 있습니다. 이 경우 생성 된 값 주석을 다른 것으로 변경할 수 있습니다. 예를 들면 다음과 같습니다. @GeneratedValue(strategy=GenerationType.IDENTITY)열에서 ID 생성을 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 2010 년

2

온라인 서버에서 localhost로 데이터베이스를 마이그레이션 한 후에도 동일한 문제에 직면했습니다. 스키마가 변경되어 각 테이블에 대해 수동으로 스키마를 정의해야했습니다.

@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

PostgreSql과 함께 SpringData JPA를 사용하고 있었고 UPDATE 호출 중에 오류가 표시되었습니다.

  • ' ResultSet을 추출 할 수 없습니다. '및 다른 항목을 .
  • org.springframework.dao.InvalidDataAccessApiUsageException : 업데이트 / 삭제 쿼리 실행; 중첩 된 예외는 javax.persistence.TransactionRequiredException : 업데이트 / 삭제 쿼리 실행 중입니다. ( 거래 표시가 필요합니다. )

실제로 두 개의 필수 주석 이 누락되었습니다 .

  • @Transactional 및
  • @Modifying

와-

@Query(vlaue = " UPDATE DB.TABLE SET Col1 = ?1 WHERE id = ?2 ", nativeQuery = true)
void updateCol1(String value, long id);

0

들어 MySQL을 가 쓰기에 좋은 생각이 아니다 마음에 걸릴 낙타 표기법 . 예를 들어 스키마가 다음과 같은 경우 :

CREATE TABLE IF NOT EXISTS `task`(
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `teaching_hours` DECIMAL(5,2) DEFAULT NULL,
    `isActive` BOOLEAN DEFAULT FALSE,
    `is_validated` BOOLEAN DEFAULT FALSE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

isActive열이로 변환 되므로 매우주의해야합니다 isactive. 따라서 Entity 클래스는 다음과 같아야합니다.

 @Basic
 @Column(name = "isactive", nullable = true)
 public boolean isActive() {
     return isActive;
 }
 public void setActive(boolean active) {
     isActive = active;
 }

그게 적어도 내 문제 였어

이것은 대소 문자를 구분하지 않는 MySql 과 관련이 없지만 Spring이 테이블을 번역하는 데 사용할 이름 지정 전략입니다. 자세한 내용은이 게시물을 참조하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.