简体   繁体   中英

Spring data using EntityManager: NullPointerException

I'm new in spring data. I'm trying to build a small java application using spring data and entitymanager. The structure of the project is the following:

在此处输入图片说明

For the spring configuration I created a class and I defined in this class beans that will be used to create an entity manager bean with this way

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();
    }

}

To be able to access to the database, I create the DAO class UserDao that allows only to create a row in the table User.

The interface IUserDao

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

The UserDao class

@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;
        }
    }

}

And that's the entity class of the User:

The User Entity

@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;
    }
}

And this is a small test of what's done

The test

public class UserTest {

    @Autowired
    UserDao userDao;

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

}

But the problem is that if I run the main I get the exception NullPointerException because userDao has as value null so the UserDao bean isn't defined. What's the problem in what I did?

In your main method you are trying to autowire something static. That is not going to work. See the longer explanation here .

For a comprehensive doc on how to perform unit testing with Spring, please read the documentation here.

You are trying to test a spring enterprise environment in a much simpler standard environment. The enterprise environment requires some setup before it will work for you. A good place to start is http://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html .

Once you get the right pieces in place it then becomes a whole lot easier and interesting to build and test.

Then you should initialize Spring Context from your junit class. The code you posted does not show this so maybe the null pointer is due to this error.

public class UserTest {

    @Autowired
    UserDao userDao;

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

}

You should annotate your class UserTest with something like:

@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);
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM