异常栈:
An exception occurred while creating a query in EntityManager:
Exception Description: Problem compiling [SELECT u FROM User u WHERE u.name=:Name AND u.pswd=:Pswd].
[14, 18] The abstract schema type 'User' is unknown.
[27, 33] The state field path 'u.name' cannot be resolved to a valid type.
[46, 52] The state field path 'u.pswd' cannot be resolved to a valid type.
java.lang.IllegalArgumentException
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1605)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366)
at com.sun.proxy.$Proxy16.createQuery(Unknown Source)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
at com.sun.proxy.$Proxy16.createQuery(Unknown Source)
at net.lab.dao.impl.UserDaoImpl.getUser(UserDaoImpl.java:45)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:198)
at com.sun.proxy.$Proxy17.getUser(Unknown Source)
at net.lab.test.UserTest.hello(UserTest.java:45)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildException(HermesParser.java:155)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.validate(HermesParser.java:347)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.populateQueryImp(HermesParser.java:278)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildQuery(HermesParser.java:163)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:142)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:116)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:102)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:86)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1603)
用Junit测试jpa时的代码:
package net.lab.test;
import java.util.List;
import net.lab.dao.UserDao;
import net.lab.entity.User;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
*
* @author xiaofanku
*/
public class UserTest extends AbstractTests implements ApplicationContextAware{
private ApplicationContext applicationContext;
private UserDao ud;
@Before
public void init(){
ud=applicationContext.getBean(UserDao.class);
}
// TODO add test methods here.
// The methods must be annotated with annotation @Test. For example:
//ngunit
@Test
public void hello() {
User qu=ud.getUser("pktmandy", "12345");
assertTrue(qu.getId()>0);
}
@Override
public void setApplicationContext(ApplicationContext ac) throws BeansException {
applicationContext=ac;
}
}
实体类:
package net.lab.entity;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
* 购买者
* @author xiaofanku
*/
@Entity(name="king_user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
/**
* 用户名
*/
@Column
private String name;
/**
* 密码
*/
@Column
private String pswd;
//GET/SET
@Override
public int hashCode() {
int hash = 7;
hash = 11 * hash + Objects.hashCode(this.id);
hash = 11 * hash + Objects.hashCode(this.name);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final User other = (User) obj;
if (!Objects.equals(this.name, other.name)) {
return false;
}
if (!Objects.equals(this.pswd, other.pswd)) {
return false;
}
if (!Objects.equals(this.id, other.id)) {
return false;
}
return true;
}
}
DAO实现类:
package net.lab.dao.impl;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import net.lab.dao.UserDao;
import net.lab.entity.User;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
*
* @author xiaofanku
*/
@Repository
public class UserDaoImpl implements UserDao{
private EntityManager em;
@PersistenceContext
public void setEntityManager(EntityManager em) {
this.em=em;
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
@Override
public long add(User user) {
em.persist(user);
return user.getId();
}
@Override
public List<User> getAll() {
return em.createQuery("SELECT u FROM User u").getResultList();
}
@Override
public User getUser(String name, String pswd) {
TypedQuery<User> q=em.createQuery("SELECT u FROM User u WHERE u.name=:Name AND u.pswd=:Pswd",User.class);
q.setParameter("Name", name);
q.setParameter("Pswd",pswd);
return q.getResultList().get(0);
}
@Override
public User getUser(long uid) {
return em.find(User.class, uid);
}
}
只需要改下User实体的注解,修改后:
package net.lab.entity;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* 购买者
* @author xiaofanku
*/
@Entity
@Table(name="king_user")
public class User implements Serializable {
//...
}
再运行测试文件
注意:
如果没有@Table注解(也就是表名加在Entity注解中),Dao中的以下方法是不会报异常的:
@Transactional(propagation=Propagation.REQUIRES_NEW)
@Override
public long add(User user) {
em.persist(user);
return user.getId();
}
@Override
public User getUser(long uid) {
return em.find(User.class, uid);
}
其它两个方法报异常的共同点它们都使用了 Java Persistence query language (JPQL),在EE中有如下介绍:
Query Language Terminology
The following list defines some of the terms referred to in this chapter:
Abstract schema: The persistent schema abstraction (persistent entities, their state, and their >relationships) over which queries
operate. The query language translates queries over this >persistent
schema abstraction into queries that are executed over the database
schema to which >entities are mapped.Abstract schema type: The type to which the persistent property of an entity evaluates in the >abstract schema. That is, each
persistent field or property in an entity has a corresponding state
field of the same type in the abstract schema. The abstract schema type of an entity is derived >from the entity class and the metadata
information provided by Java language annotations.Backus-Naur Form (BNF): A notation that describes the syntax of high-level languages. The >syntax diagrams in this chapter are in BNF
notation.Navigation: The traversal of relationships in a query language expression. The navigation >operator is a period.
Path expression: An expression that navigates to a entity’s state or relationship field.
State field: A persistent field of an entity.
Relationship field: A persistent relationship field of an entity whose type is the abstract schema type of the related entity.
环境:
JDK: 1.7.0_79
Spring: 3.2.7
EclipseLink: 2.1
JUnit: 4.12
参考网址:
JPA’s Nasty “Unknown abstract schema type” Error
The Java EE 6 Tutorial