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
)
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
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")
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.
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.
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;
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")