【问题标题】:Spring data using EntityManager: NullPointerException使用 EntityManager 的 Spring 数据:NullPointerException
【发布时间】:2016-01-13 15:00:19
【问题描述】:

我是春季数据的新手。我正在尝试使用 Spring Data 和 entitymanager 构建一个小型 Java 应用程序。项目结构如下:

对于 spring 配置,我创建了一个类,并在该类中定义了将用于通过这种方式创建实体管理器 bean 的 bean

SpringConfiguration:

@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-mysql.properties" })
@ComponentScan({ "com.spring.data.persistence" })
public class SpringConfiguration implements TransactionManagementConfigurer{

    @Autowired
    private Environment env;

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();

        driverManagerDataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        driverManagerDataSource.setUrl(env.getProperty("jdbc.url"));
        driverManagerDataSource.setUsername(env.getProperty("jdbc.user"));
        driverManagerDataSource.setPassword(env.getProperty("jdbc.pass"));
        return driverManagerDataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        localContainerEntityManagerFactoryBean.setDataSource(dataSource());
        localContainerEntityManagerFactoryBean.setJpaDialect(jpaDialect());
        localContainerEntityManagerFactoryBean.setPackagesToScan(new String[] { "com.spring.data.persistence.model" });
        localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaAdapter());
        return localContainerEntityManagerFactoryBean;
    }

    @Bean
    public HibernateJpaVendorAdapter jpaAdapter() {
        HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
        Boolean showSql = true;
        hibernateJpaVendorAdapter.setShowSql(showSql);
        hibernateJpaVendorAdapter.setDatabasePlatform(env.getProperty("hibernate.dialect"));
        hibernateJpaVendorAdapter.setGenerateDdl(false);
        return hibernateJpaVendorAdapter;
    }

    @Bean
    public JpaDialect jpaDialect() {
        return new HibernateJpaDialect();
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
        PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor = new PersistenceExceptionTranslationPostProcessor();
        persistenceExceptionTranslationPostProcessor.setRepositoryAnnotationType(Repository.class);
        return persistenceExceptionTranslationPostProcessor;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        EntityManagerFactory entityManagerFactory = entityManagerFactory().getObject();
        return new JpaTransactionManager(entityManagerFactory);
    }

    @Bean
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return transactionManager();
    }

}

为了能够访问数据库,我创建了 DAO 类 UserDao,它只允许在表 User 中创建一行。

IUserDao 界面

public interface IUserDao {
    public User create(User user);
}

UserDao 类

@Repository
public class UserDao implements IUserDao{

    @PersistenceContext
    private EntityManager entityManager;

    public UserDao()
    {
        super();
    }
    public User create(User user) {
        try {
            this.entityManager.persist(user);
            return user;
        } catch (PersistenceException ex) {
            ex.printStackTrace();
            return null;

        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
            return null;
        }
    }

}

这就是用户的实体类:

用户实体

@Entity
public class User {
    @Id
    @GeneratedValue
    @Column(name="USER_ID")
    private int id;

    @Column(name="USER_NAME")
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

这是对所做工作的一个小测试

测试

public class UserTest {

    @Autowired
    UserDao userDao;

    @Test
    public void test() {
        User user=new User();
        user.setName("User1");
        userDao.create(user);
    }

}

但问题是,如果我运行 main,我会得到异常 NullPointerException,因为 userDao 的值为 null,因此未定义 UserDao bean。 我做的有什么问题?

【问题讨论】:

标签: java spring hibernate spring-data spring-data-jpa


【解决方案1】:

您正在尝试在更简单的标准环境中测试 Spring Enterprise 环境。企业环境需要一些设置才能为您工作。一个好的起点是http://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html

一旦你得到正确的部分,那么构建和测试就会变得更加容易和有趣。

【讨论】:

    【解决方案2】:

    在你的主要方法中,你试图自动连接一些静态的东西。那是行不通的。详细解释见here

    有关如何使用 Spring 执行单元测试的综合文档,请在此处阅读documentation

    【讨论】:

    • Spring 应用程序上下文也不应该在 main 方法中以某种方式启动吗? @Autowired 如何在 Main 类中工作?
    • 我刚刚更新了帖子。我在一个单元测试用例中进行了测试。我遇到了同样的问题
    • 我为这个答案添加了一个额外的链接。很抱歉没有先详细介绍,但是您的测试代码还远未完成(所以我只是指出了第一个问题)。我猜剩下的代码不是你写的,你在学习Spring,对吧?在这种情况下,您应该真正阅读有关测试的整个文档(上面的链接)。
    • 我不知道的是Junit,我正在学习spring-data。我刚刚在测试类中添加了这个注解:@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { SpringConfiguration.class }, loader = AnnotationConfigContextLoader.class)
    【解决方案3】:

    然后你应该从你的 junit 类初始化 Spring Context。您发布的代码没有显示这一点,因此空指针可能是由于此错误造成的。

    public class UserTest {
    
        @Autowired
        UserDao userDao;
    
        @Test
        public void test() {
            User user=new User();
            user.setName("User1");
            userDao.create(user);
        }
    
    }
    

    您应该使用以下内容注释您的类 UserTest:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = SpringConfiguration.class, loader = AnnotationConfigContextLoader.class)
    public class UserTest {
        @Autowired
        UserDao userDao;
    
        @Test
        public void test() {
            User user=new User();
            user.setName("User1");
            userDao.create(user);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多