web-dev-qa-db-fra.com

impossible d'extraire ResultSet en veille prolongée

J'ai un problème dans Hibernate . J'essaye d'analyser List mais il lève une exception: HTTP Status 500 - could not extract ResultSet. Lors du débogage, cela se produit à la ligne query.list() .. 

Mon exemple de code ici

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

}

Mes haricots

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

Exception:

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)

Ma base de données:

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

L'annotation @JoinColumn spécifie le nom de la colonne utilisée en tant que clé étrangère sur l'entité ciblée. 

Dans la classe Product ci-dessus, le nom de la colonne de jointure est défini sur ID_CATALOG.

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

Cependant, la clé étrangère de la table Product s'appelle catalog_id.

`catalog_id` int(11) DEFAULT NULL,

Vous devrez modifier le nom de la colonne sur la table ou le nom que vous utilisez dans le @JoinColumn afin qu'ils correspondent. Voir http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-association

49
Will Keeling

Une autre cause potentielle, pour d'autres personnes rencontrant le même message d'erreur, est que cette erreur se produira si vous accédez à une table dans un schéma différent de celui que vous avez authentifié.

Dans ce cas, vous devez ajouter le nom du schéma à votre entrée d'entité:

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

Essayez d'utiliser une jointure interne dans votre requête.

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

également dans le fichier de configuration hibernate ont 

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

Pour afficher ce qui est interrogé sur la console.

4
Lakshmi

J'ai eu le même problème. Essayez d'utiliser l'éditeur HQL. Il vous affichera le SQL (comme vous avez une exception de grammaire SQL). Copiez votre code SQL et exécutez-le séparément. Dans mon cas, le problème était dans la définition du schéma. J'ai défini le schéma, mais je devrais le laisser vide. Cela a soulevé la même exception que vous avez. Et la description de l'erreur reflétait l'état réel, car le nom du schéma était inclus dans l'instruction SQL. 

2
Gico

Si vous n'avez pas de séquence 'HIBERNATE_SEQUENCE' créée dans la base de données (si vous utilisez Oracle ou une base de données basée sur une séquence), vous obtiendrez le même type d'erreur.

Assurez-vous que la séquence y est présente;

1

J'ai rencontré le même problème après la migration d'une base de données d'un serveur en ligne vers localhost. Le schéma a changé alors je devais définir le schéma manuellement pour chaque table:

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