ResultSet konnte im Ruhezustand nicht extrahiert werden

78

Ich habe ein Problem mit dem Ruhezustand . Ich versuche, List zu analysieren, aber es wird eine Ausnahme ausgelöst : HTTP Status 500 - could not extract ResultSet. Wenn ich debugge, ist es ein Fehler in der Leitung query.list()...

Mein Beispielcode hier

@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;
}

}

Meine Bohnen

  <!-- 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"/>

Ausnahme:

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)

Meine Datenbank:

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
)
Thanh Duy Ngo
quelle

Antworten:

75

Die @JoinColumnAnmerkung gibt den Namen der Spalte an, die als Fremdschlüssel für die Zielentität verwendet wird.

In der Productobigen Klasse wird der Name der Join-Spalte auf gesetzt ID_CATALOG.

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

Der Fremdschlüssel in der ProductTabelle wird jedoch aufgerufencatalog_id

`catalog_id` int(11) DEFAULT NULL,

Sie müssen entweder den Spaltennamen in der Tabelle oder den Namen, den Sie in der Tabelle verwenden, so ändern @JoinColumn, dass sie übereinstimmen. Siehe http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-association

Will Keeling
quelle
26

Eine weitere mögliche Ursache für andere Personen, die auf dieselbe Fehlermeldung stoßen, ist, dass dieser Fehler auftritt, wenn Sie auf eine Tabelle in einem anderen Schema als dem zugreifen, bei dem Sie sich authentifiziert haben.

In diesem Fall müssten Sie den Schemanamen zu Ihrem Entitätseintrag hinzufügen:

@Table(name= "catalog", schema = "targetSchemaName")
sweetfa
quelle
Es trat in meinem Fall auf, als ich versuchte, eine neue sboot -mysql -jpa App zu erstellen. Es wurde keine DB-Tabelle erstellt. Dies löste mein Problem.
Suraj Patil
oder wenn der Tabellenname nicht übereinstimmt ... wie @Table(name = "catalog", schema = "taretSchemaName")und der Tabellenname ist taretSchemaName.
Paolo
6

Versuchen Sie, Inner Join in Ihrer Abfrage zu verwenden

    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();

auch in der Hibernate-Konfigurationsdatei haben

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

Anzeigen, was auf der Konsole abgefragt wird.

Lakshmi
quelle
4

Ich hatte ein ähnliches Problem. Versuchen Sie es mit dem HQL-Editor. Es zeigt Ihnen die SQL an (da Sie eine SQL-Grammatikausnahme haben). Kopieren Sie Ihre SQL und führen Sie sie separat aus. In meinem Fall lag das Problem in der Schemadefinition. Ich habe das Schema definiert, aber ich sollte es leer lassen. Dies hat die gleiche Ausnahme ausgelöst wie Sie. Die Fehlerbeschreibung spiegelte den tatsächlichen Status wider, da der Schemaname in der SQL-Anweisung enthalten war.

Gico
quelle
4

Wenn Sie keine 'HIBERNATE_SEQUENCE'-Sequenz in der Datenbank erstellt haben (wenn Sie Oracle oder eine sequenzbasierte Datenbank verwenden), wird derselbe Fehlertyp angezeigt.

Stellen Sie sicher, dass die Sequenz dort vorhanden ist.

Mohammad Badiuzzaman
quelle
5
Könnten Sie näher darauf eingehen?
Samisnotinsane
Wenn Sie Oracle DB verwenden und die automatische Schemaerstellung deaktiviert haben, fehlt Ihnen wahrscheinlich auch die Sequenz HIBERNATE_SEQUENCE. Wenn dies der Fall ist, können Sie versuchen, die generierte @GeneratedValue(strategy=GenerationType.IDENTITY)Wertanmerkung in etwas anderes zu ändern, z. B .: Wenn Sie die Identitätsgenerierung in Ihrer Spalte verwendenid NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
Glogo
4

Ich habe die folgenden Eigenschaften in meiner Datei application.properties verwendet und das Problem wurde behoben

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

und

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

früher wurde ein Fehler bekommen

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)
Saurabh Verma
quelle
Ich denke, dies ist die (manchmal bessere) Alternative zum expliziten Annotieren mit @Table (name = "catalog", schema = "targetSchemaName"), wie oben vorgeschlagen. Besser, denn wenn Sie Code aus einer EE-Anwendung kopieren, müssen Sie die Entitätsklassen nicht ändern.
user2081279
4

Ich hatte das gleiche Problem, als ich versuchte, eine Zeile zu aktualisieren:

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

Mein Problem war, dass ich vergessen habe, die @ModifyingAnmerkung hinzuzufügen :

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

Ich hatte das gleiche Problem, nachdem ich eine Datenbank vom Online-Server auf localhost migriert hatte. Das Schema wurde geändert, sodass ich das Schema für jede Tabelle manuell definieren musste:

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

Eine andere Lösung ist das Hinzufügen von @JsonIgnore:

@OneToMany(mappedBy="catalog", fetch = FetchType.LAZY)
@JsonIgnore
private Set<Product> products = new HashSet<Product>(0);
Thadian
quelle
11
Erklären Sie, wie dies das Problem lösen würde, Kumpel. Der Antwortsuchende würde mehr davon profitieren, wenn er die Lösung versteht.
Rai
0

Ich habe Spring Data JPA mit PostgreSql verwendet und während des UPDATE-Aufrufs wurden Fehler angezeigt.

  • ' ResultSet konnte nicht extrahiert werden ' und ein anderes.
  • org.springframework.dao.InvalidDataAccessApiUsageException: Ausführen einer Aktualisierungs- / Löschabfrage; verschachtelte Ausnahme ist javax.persistence.TransactionRequiredException: Ausführen einer Aktualisierungs- / Löschabfrage. ( Anzeigen der Transaktion erforderlich. )

Eigentlich fehlten mir zwei erforderliche Anmerkungen.

  • @Transactional und
  • @ Modifizieren

Mit-

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