使用Hibernate遇到的各種異常坑
阿新 • • 發佈:2018-12-23
前言
今天使用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
謝謝你的支援。