JPA + DAO + Spring:配置错误

时间:2012-01-29 22:50:37

标签: java spring junit

我正试图用春天来运行我的第一个例子。所以我下载了SpringSource Tool Suite,并从模板创建了一个jpa项目。

我有一个mysql数据库,我在其中创建了一个User表。所以我创建了用户类:

import java.io.Serializable;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlRootElement;

import java.util.Date;
import java.util.Set;


/**
 * The persistent class for the user database table.
 * 
 */
@XmlRootElement(name="User")
@Entity
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private String username;

    private String cellphone;

    private int currentlat;

    private int currentlon;

    private String email;

    @Lob()
    private byte[] foto;

    @Temporal( TemporalType.TIMESTAMP)
    private Date lastgpsdate;

    private String name;

    private String notes;

    private String password;

    private String surname;

    //bi-directional many-to-one association to FavoriteSport
    @OneToMany(mappedBy="user")
    private Set<FavoriteSport> favoriteSports;

    //bi-directional many-to-one association to FavoriteSpot
    @OneToMany(mappedBy="user")
    private Set<FavoriteSpot> favoriteSpots;

    //bi-directional many-to-one association to FavoriteUser
    @OneToMany(mappedBy="user1")
    private Set<FavoriteUser> favoriteUsers1;

    //bi-directional many-to-one association to FavoriteUser
    @OneToMany(mappedBy="user2")
    private Set<FavoriteUser> favoriteUsers2;

    //bi-directional many-to-one association to SpotReview
    @OneToMany(mappedBy="user")
    private Set<SpotReview> spotReviews;

    //bi-directional many-to-one association to Role
    @ManyToOne
    @JoinColumn(name="role_idrole")
    private Role role;

    //bi-directional many-to-one association to UserAccount
    @OneToMany(mappedBy="user")
    private Set<UserAccount> userAccounts;

    public User() {
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getCellphone() {
        return this.cellphone;
    }

    public void setCellphone(String cellphone) {
        this.cellphone = cellphone;
    }

    public int getCurrentlat() {
        return this.currentlat;
    }

    public void setCurrentlat(int currentlat) {
        this.currentlat = currentlat;
    }

    public int getCurrentlon() {
        return this.currentlon;
    }

    public void setCurrentlon(int currentlon) {
        this.currentlon = currentlon;
    }

    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public byte[] getFoto() {
        return this.foto;
    }

    public void setFoto(byte[] foto) {
        this.foto = foto;
    }

    public Date getLastgpsdate() {
        return this.lastgpsdate;
    }

    public void setLastgpsdate(Date lastgpsdate) {
        this.lastgpsdate = lastgpsdate;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNotes() {
        return this.notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSurname() {
        return this.surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public Set<FavoriteSport> getFavoriteSports() {
        return this.favoriteSports;
    }

    public void setFavoriteSports(Set<FavoriteSport> favoriteSports) {
        this.favoriteSports = favoriteSports;
    }

    public Set<FavoriteSpot> getFavoriteSpots() {
        return this.favoriteSpots;
    }

    public void setFavoriteSpots(Set<FavoriteSpot> favoriteSpots) {
        this.favoriteSpots = favoriteSpots;
    }

    public Set<FavoriteUser> getFavoriteUsers1() {
        return this.favoriteUsers1;
    }

    public void setFavoriteUsers1(Set<FavoriteUser> favoriteUsers1) {
        this.favoriteUsers1 = favoriteUsers1;
    }

    public Set<FavoriteUser> getFavoriteUsers2() {
        return this.favoriteUsers2;
    }

    public void setFavoriteUsers2(Set<FavoriteUser> favoriteUsers2) {
        this.favoriteUsers2 = favoriteUsers2;
    }

    public Set<SpotReview> getSpotReviews() {
        return this.spotReviews;
    }

    public void setSpotReviews(Set<SpotReview> spotReviews) {
        this.spotReviews = spotReviews;
    }

    public Role getRole() {
        return this.role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    public Set<UserAccount> getUserAccounts() {
        return this.userAccounts;
    }

    public void setUserAccounts(Set<UserAccount> userAccounts) {
        this.userAccounts = userAccounts;
    }

}

然后我定义了Dao结构和JpaDaoUser的实现

public interface Dao <E, K> {
    void persist(E entity);
    void remove(E entity);
    E findById(K id);
}

import java.lang.reflect.ParameterizedType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

public abstract class JpaDao <E, K> implements Dao<E, K> {
    protected Class<E> entityClass;

    @PersistenceContext
    protected EntityManager entityManager;

    public JpaDao() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
        this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
    }

    public void persist(E entity) { entityManager.persist(entity); }

    public void remove(E entity) { entityManager.remove(entity); }

    public E findById(K id) { return entityManager.find(entityClass, id); }
}

import org.springframework.stereotype.Repository;

@Repository
public class JpaDaoUser extends JpaDao<User, String> implements DaoUser {
}

对于JPA配置,我使用了模板生成的默认类:

@Configuration
public class JpaConfiguration {

    @Value("#{dataSource}")
    private javax.sql.DataSource dataSource;

    @Bean
    public Map<String, Object> jpaProperties() {
        Map<String, Object> props = new HashMap<String, Object>();
        props.put("hibernate.dialect", H2Dialect.class.getName());
        props.put("hibernate.cache.provider_class", HashtableCacheProvider.class.getName());
        return props;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
        hibernateJpaVendorAdapter.setShowSql(false);
        hibernateJpaVendorAdapter.setGenerateDdl(true);
        hibernateJpaVendorAdapter.setDatabase(Database.H2);
        return hibernateJpaVendorAdapter;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new JpaTransactionManager( localContainerEntityManagerFactoryBean().getObject() );
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean() {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(this.dataSource);
        lef.setJpaPropertyMap(this.jpaProperties());
        lef.setJpaVendorAdapter(this.jpaVendorAdapter());
        return lef;
    }

}

最后我修改了测试类(在测试文件夹中)来测试我的简单项目

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class UserPersistenceTests {

    @Autowired
    public JpaDaoUser du;

    @Test
    public void test1() throws Exception {
        assertEquals("danilo", du.findById("danilo").getUsername());
    }

}

我遇到了以下问题

java.lang.IllegalArgumentException: Unknown entity: java.lang.String
    at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:626)
    at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:589)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
    at $Proxy26.find(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
    at $Proxy26.find(Unknown Source)
    at com.windy.spring.JpaDao.findById(JpaDao.java:23)
    at com.windy.spring.OrderPersistenceTests.testSaveAndGet(OrderPersistenceTests.java:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
    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.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.MappingException: Unknown entity: java.lang.String
    at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:691)
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:92)
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090)
    at org.hibernate.impl.SessionImpl.get(SessionImpl.java:1005)
    at org.hibernate.impl.SessionImpl.get(SessionImpl.java:998)
    at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:614)
    ... 43 more

我能理解为什么会出现这个错误(我检查过我的数据库中存在的条目)?

提前感谢您的帮助

Danilo的

1 个答案:

答案 0 :(得分:2)

java.lang.IllegalArgumentException: Unknown entity: java.lang.String
   at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:626)

这基本上归结为你正在做的事情如下:

String string = entityManager.find(String.class, id);

因此没有任何意义。让我们在您正在执行此操作的代码中进行跟踪。您的错误出在genericSuperclass.getActualTypeArguments()[1]构造函数的JpaDao调用中:

public JpaDao() {
    ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
    this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
}

数组索引是从0开始的,所以你基本上抓住了JpaDao<User, String> String的第二个元素。相应地修复它。


关于你的新问题,

  

显示java.lang.NullPointerException          在com.windy.spring.PersistenceTests.test1(UserPersistenceTests.java:22)

这仅表示du.findById("danilo")返回null。那是一个不同的问题。它至少证实你的Hibernate和DAO部分现在正常工作。很可能你在数据库中没有与此ID匹配的记录。