我在这个主题上提到我的最后一个问题,你可以在这里找到:MySQL Syntax Error by combining CASE and LIMIT (only sometimes) - generated by JPA
错误发生但我发现了一些有趣的事实。但首先这里是我的结构: 我使用的是JSF 2.2,Java EE,JPA和MySQL。 Web应用程序在Glassfish 4.1服务器中运行。
JSF-View从以下View-Controller调用列表:
@javax.faces.view.ViewScoped
@Named
public class ControllerErfolgskontrolle extends ControllerAbstract {
@Inject
private SvEnGenerierteAufgabe svEnGenerierteAufgabe;
private List<EntityGenerierteAufgabe> generierteAufgabenBenutzer;
@PostConstruct
private void doInit() {
generierteAufgabenBenutzer = svEnGenerierteAufgabe.getByLimitedSorted(
getControllerSession().getBenutzer());
}
public List<EntityGenerierteAufgabe> getGenerierteAufgabenBenutzer() {
return generierteAufgabenBenutzer;
}
}
View-Contorller从EJB SvEnGenrierteAufgabe收到相关列表(generierteAufgabenBenutzer):
@javax.ejb.Stateless
public class SvEnGenerierteAufgabe {
@PersistenceContext
EntityManager em;
public List<EntityGenerierteAufgabe> getByLimitedSorted(EntityBenutzer benutzer) {
String query = "SELECT ga, "
+ " CASE WHEN (ga.changeTime > ga.createTime) THEN ga.changeTime "
+ " ELSE ga.createTime END AS myorder "
+ "FROM EntityGenerierteAufgabe ga "
+ "WHERE ga.benutzer=:benutzer "
+ "ORDER BY myorder DESC";
List<EntityGenerierteAufgabe> aufgaben = new ArrayList<>();
List<Object[]> results = null;
results = em.createQuery(query)
.setParameter("benutzer", benutzer)
.setMaxResults(6)
.getResultList();
for (Object[] result : results) {
aufgaben.add((EntityGenerierteAufgabe) result[0]);
}
return aufgaben;
}
}
在大多数情况下,一切正常并且符合预期。但是,当我通过jMeter对至少两个不同的线程进行压力测试时,EntityManager SOMETIMES无法以正确的方式创建MySQL-Query,并导致MySQLSyntaxErrorException,如下所示:
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM ENTITYGENERIERTEAUFGABE WHERE (BENUTZER_ID = 2) ORDER BY CASE WHEN (CHANGE' at line 1
Error Code: 1064
Call: SELECT ID AS a1, BEARBEITUNGSZEIT AS a2, CHANGETIME AS a3, CREATETIME AS a4, FORTSCHRITT AS a5, ISTBEENDET AS a6, AUFGABENTYP_ID AS a7, LEVEL_ID AS a8, BENUTZER_ID AS a9, CASE WHEN (CHANGETIME > CREATETIME) THEN CHANGETIME WHEN CREATETIME THEN FROM ENTITYGENERIERTEAUFGABE WHERE (BENUTZER_ID = ?) ORDER BY CASE WHEN (CHANGETIME > CREATETIME) THEN CHANGETIME WHEN CREATETIME THEN DESC LIMIT ?, ?
bind => [3 parameters bound]
Query: ReportQuery(referenceClass=EntityGenerierteAufgabe sql="SELECT ID AS a1, BEARBEITUNGSZEIT AS a2, CHANGETIME AS a3, CREATETIME AS a4, FORTSCHRITT AS a5, ISTBEENDET AS a6, AUFGABENTYP_ID AS a7, LEVEL_ID AS a8, BENUTZER_ID AS a9, CASE WHEN (CHANGETIME > CREATETIME) THEN CHANGETIME WHEN CREATETIME THEN FROM ENTITYGENERIERTEAUFGABE WHERE (BENUTZER_ID = ?) ORDER BY CASE WHEN (CHANGETIME > CREATETIME) THEN CHANGETIME WHEN CREATETIME THEN DESC LIMIT ?, ?")
at ...
实际语法错误是WHEN CREATETIME THEN
部分,根本不属于那里。
我假设某些无状态实例与不同的EntityManager实例之间存在竞争条件,这导致EntityManager有时会构建错误的SQL。
这只是一个想法,但当我用@ javax.ejb.Singleton替换@ javax.ejb.Stateless时一切正常。所以我的问题是:我做错了什么?据我所知,有一个无状态实例池,每个客户端(在本例中为ViewController)都为方法调用获取自己的实例,然后实例返回池中。
答案 0 :(得分:0)
我做了一些测试: 我使用 Hibernate 作为JPA-Provider而不是 EclipseLink ,结果是错误不再发生。
那么EclipseLink实现中是否存在可能的错误?