我在 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
)
答案 0 :(得分:52)
@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
答案 1 :(得分:13)
对于遇到相同错误消息的其他人来说,另一个可能的原因是,如果您访问的是与您已通过身份验证的模式不同的模式中的表,则会发生此错误。
在这种情况下,您需要将模式名称添加到实体条目中:
@Table(name= "catalog", schema = "targetSchemaName")
答案 2 :(得分:4)
尝试在查询中使用内部联接
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配置文件中有
<!--hibernate.cfg.xml -->
<property name="show_sql">true</property>
显示控制台上正在查询的内容。
答案 3 :(得分:3)
我有类似的问题。尝试使用HQL编辑器。它将显示SQL(因为您有SQL语法异常)。复制SQL并单独执行。就我而言,问题出在架构定义中。我定义了架构,但我应该把它留空。这引起了同样的例外。并且错误描述反映了实际状态,因为模式名称包含在SQL语句中。
答案 4 :(得分:2)
如果您没有在数据库中创建'HIBERNATE_SEQUENCE'序列(如果使用oracle或任何基于序列的数据库),您将得到相同类型的错误;
确保序列存在;
答案 5 :(得分:1)
将数据库从在线服务器迁移到本地主机后,我遇到了同样的问题。模式已更改,因此我必须为每个表手动定义模式:
@Entity
@Table(name = "ESBCORE_DOMAIN", schema = "SYS")
答案 6 :(得分:0)
另一种解决方案是添加@JsonIgnore:
angular.mock.module(($provider: ng.auto.IProvideService) => {
$provider.value('service', jasmine.createSpyObj('service', ['list of accessed modules']);
});
答案 7 :(得分:0)
我在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)
答案 8 :(得分:0)
当我尝试更新一行时,我遇到了同样的问题:
@Query(value = "UPDATE data SET value = 'asdf'", nativeQuery = true)
void setValue();
我的问题是我忘记添加@Modifying
批注:
@Modifying
@Query(value = "UPDATE data SET value = 'asdf'", nativeQuery = true)
void setValue();
答案 9 :(得分:0)
我正在将Spring Data JPA与PostgreSql一起使用,并且在UPDATE调用期间它显示了错误-
实际上,我缺少两个必需的注释。
使用-
@Query(vlaue = " UPDATE DB.TABLE SET Col1 = ?1 WHERE id = ?2 ", nativeQuery = true)
void updateCol1(String value, long id);
答案 10 :(得分: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
。
所以在你的实体类中应该是这样的:
@Basic
@Column(name = "isactive", nullable = true)
public boolean isActive() {
return isActive;
}
public void setActive(boolean active) {
isActive = active;
}
那是我的问题,至少让我犯了你的错误
这与不区分大小写的 MySql 无关,而是 spring 用于转换表的命名策略。 有关更多信息,请参阅此 post
答案 11 :(得分:0)
如果您错误地为表使用了保留关键字 (https://dev.mysql.com/doc/refman/8.0/en/keywords.html#keywords-8-0-detailed-C),也会出现此消息。当对名称为 sama 作为保留 mysql 关键字的表进行连接时,您会得到相同的消息,尽管其他一切都是正确的。 希望这会为其他人节省一些时间和痛苦。