使用Hibernate遇到的各种异常坑
前言
今天使用SpringBoot整合Hibernate的时候测试的时候遇到一些异常问题,准备总结一下。把问题记录下来,希望能够帮助大家解决。
整合环境
- SpringBoot 2.1.1
- JDK1.8
- Hibernate5.3.7
异常一
异常信息如下
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException: Legacy-style query parameters (`?`) are no longer supported;
use JPA-style ordinal parameters (e.g., `?1`) instead : FROM com.wip.hibernate.dao.entity.Article as a WHERE a.title = ? and a.category = ? [FROM com.wip.hibernate.dao.entity.Article as a WHERE a.title = ? and a.category = ?];
nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: Legacy-style query parameters (`?`) are no longer supported;
use JPA-style ordinal parameters (e.g., `?1`) instead : FROM com.wip.hibernate.dao.entity.Article as a WHERE a.title = ? and a.category = ? [FROM com.wip.hibernate.dao.entity.Article as a WHERE a.title = ? and a.category = ?]
Caused by: org.hibernate.QueryException: Legacy-style query parameters (`?`) are no longer supported;
use JPA-style ordinal parameters (e.g., `?1`) instead : FROM com.wip.hibernate.dao.entity.Article as a WHERE a.title = ? and a.category = ? [FROM com.wip.hibernate.dao.entity.Article as a WHERE a.title = ? and a.category = ?]
Caused by: org.hibernate.QueryException: Legacy-style query parameters (`?`) are no longer supported; use JPA-style ordinal parameters (e.g., `?1`) instead : FROM com.wip.hibernate.dao.entity.Article as a WHERE a.title = ? and a.category = ?
代码如下(Dao)
下面代码主要写了一个查询,查询文章标题和分类是否同时间存在,用的是点位设置参数的方式,在其他博主看到说Hibernate4.1之后对于HQL中查询的点位符做了改进,由于我这里是使用的老式的点位符所以报了上面的异常。
public boolean articleExists(String title, String category) {
String hql = "FROM Article as a WHERE a.title = ? and a.category = ?";
int count = entityManager.createQuery(hql).setParameter(0, title)
.setParameter(1, category).getResultList().size();
return count > 0;
}
解决办法
从告警提示信息中可以看出,它建议用命名参数或者JPA占位符两中种方法来代替老的占位符查询方法。
方法一,改成命名参数的方式
public boolean articleExists(String title, String category) {
String hql = "FROM Article as a WHERE a.title = :title and a.category = :category";
int count = entityManager.createQuery(hql).setParameter("title", title)
.setParameter("category", category).getResultList().size();
return count > 0;
}
方法二:改成JPA点位符的方式
public boolean articleExists(String title, String category) {
String hql = "FROM Article as a WHERE a.title = ?0 and a.category = ?1";
int count = entityManager.createQuery(hql).setParameter(0, title)
.setParameter(1, category).getResultList().size();
return count > 0;
}
注意:其中
"?"
后面的"0"
代表索引位置,在HQL名句中可以重复出现,并不一定是从0开始,可以是任何数字,只是参数要与期对应上。- 采用后面两种查询方法修改后就不会有异常产生了,个人推荐使用
方法一
,看起来更直观一点,性能方面相对也会好一点。 日志打印成功SQL语句
select
article0_.article_id as article_1_0_,
article0_.category as category2_0_,
article0_.title as title3_0_
from
articles article0_
where
article0_.title=?
and article0_.category=?
异常二
异常信息如下
org.springframework.dao.InvalidDataAccessApiUsageException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call;
nested exception is javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
Caused by: javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
代码如下(Service)
下面代码先是判断文章文章是否存在,不存在则执行添加方法。
public synchronized boolean addArticle(Article article) {
if (articleDao.articleExists(article.getTitle(),article.getCategory())) {
return false;
} else {
articleDao.addArticle(article);
return true;
}
}
解决办法
由于使用EntityManager
的时候在进行增删改
的时候需要添加事务Transactional
,由于我这里没有加所以出现上面异常。
添加
@Transactional
即可@Transactional
public synchronized boolean addArticle(Article article) {if (articleDao.articleExists(article.getTitle(),article.getCategory())) {
return false;
} else {
articleDao.addArticle(article);
return true;
}
}
注意,添加事务可以直接在方法上添加,也可以直接在类上添加,在类上添加的话代表每个方法都代有事务。
日志打印添加成功SQL语句
insert
into
articles
(category, title)
values
(?, ?)
异常三
异常信息如下
org.springframework.dao.InvalidDataAccessResourceUsageException: error performing isolated work;
SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: error performing isolated work
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'bucket_test.hibernate_sequence' doesn't exist
代码如下
这里同样是执行添加方法的时候出错的,看到其它博主说是ID自增的问题,我这里设置的是GenerationType.AUTO
,所以会出现上面异常。
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "article_id")
private int articleId;
解决办法
在实体类上修改@GeneratedValue
的strategy即可,将AUTO
属性改成IDENTITY
属性。
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "article_id")
private int articleId;
- 最后完美解决。
以上是我遇到的一些坑,后续会持续更新,有问题欢迎留言,看到第一时间回复。
最后附上:SpringBoot整合全家桶 欢迎star
谢谢你的支持。
还没有评论,来说两句吧...