java - Spring boot 无法运行,但服务 UTest 运行良好

标签 java spring-boot spring-data-jpa

第一次尝试使用 Spring Boot 创建项目,数据。我无法在实体管理器中运行 NullPointerException 项目,但服务测试运行良好。

主类:

@SpringBootApplication(scanBasePackages = {"SpringDataComponents"})
public class TestMain implements CommandLineRunner {


@Autowired
PortService portService;

public static void main(String[] args) {
    new SpringApplicationBuilder(TestMain.class)
.web(WebApplicationType.NONE).run(args);
}

@Override
public void run(String... args) {
    portService.addPort(CreatePort.getPort());

    System.out.println(portService.getAll().get(0).getName());

}
}

配置:

@Configuration
@EnableTransactionManagement
@ComponentScan("SpringDataComponents")
@PropertySource("classpath:app.properties")
@EnableJpaRepositories("SpringDataComponents.repository")
public class DataConfig {

private static final String PROP_DATABASE_DRIVER = "db.driver";
private static final String PROP_DATABASE_PASSWORD = "db.password";
private static final String PROP_DATABASE_URL = "db.url";
private static final String PROP_DATABASE_USERNAME = "db.username";
private static final String PROP_HIBERNATE_DIALECT = "db.hibernate.dialect";
private static final String PROP_HIBERNATE_SHOW_SQL = "db.hibernate.show_sql";
private static final String PROP_ENTITYMANAGER_PACKAGES_TO_SCAN = "db.entitymanager.packages.to.scan";
private static final String PROP_HIBERNATE_HBM2DDL_AUTO = "db.hibernate.hbm2ddl.auto";

@Resource
private Environment env;

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

dataSource.setDriverClassName(env.getRequiredProperty(PROP_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROP_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROP_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROP_DATABASE_PASSWORD));

return dataSource;
}

@Bean
public JpaVendorAdapter jpaVendorAdapter() {
    HibernateJpaVendorAdapter jpaVendorAdapter = new 
HibernateJpaVendorAdapter();
jpaVendorAdapter.setGenerateDdl(true);
jpaVendorAdapter.setShowSql(true);
jpaVendorAdapter.setDatabasePlatform(env.getRequiredProperty(PROP_HIBERNATE_DIALECT));

return jpaVendorAdapter;
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan(env.getRequiredProperty(PROP_ENTITYMANAGER_PACKAGES_TO_SCAN));
 //   entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
    entityManagerFactoryBean.setJpaProperties(getHibernateProperties());

return entityManagerFactoryBean;
}

@Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

return transactionManager;
}

private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put(PROP_HIBERNATE_DIALECT, env.getRequiredProperty(PROP_HIBERNATE_DIALECT));
properties.put(PROP_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROP_HIBERNATE_SHOW_SQL));
properties.put(PROP_HIBERNATE_HBM2DDL_AUTO, env.getRequiredProperty(PROP_HIBERNATE_HBM2DDL_AUTO));

return properties;
}

}

应用程序属性

#DB properties:
db.driver=org.postgresql.Driver
db.url=jdbc:postgresql://localhost:5432/postgres
db.username=postgres
db.password=qwe123qwe

#Hibernate Configuration:
db.hibernate.dialect=org.hibernate.dialect.PostgreSQL95Dialect
db.hibernate.show_sql=true
db.entitymanager.packages.to.scan=SpringDataComponents.entity
db.hibernate.hbm2ddl.auto = create-drop

存储库:

@Repository
public interface PortRepository extends JpaRepository<Port, Integer> {

@Query("select b from Port b where b.name =: name")
Port findByName(@Param("name") String name);
}

服务:

@Service("portService")
@Transactional
public class PortService implements PortServiceInterface {

@Autowired
PortRepository portRepository;

@Override
public Port addPort(Port port) {
Port savedPort = portRepository.saveAndFlush(port);
return savedPort;
}

@Override
public void delete(Integer id) {
portRepository.deleteById(id);
}

@Override
public Port getByName(String name) {
return portRepository.findByName(name);
}

@Override
public Port editPort(Port port) {
return portRepository.saveAndFlush(port);
}

@Override
public List<Port> getAll() {
return portRepository.findAll();
}
}

实体:

@Entity
@Table(name = "port")
public class Port {

@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name= "increment", strategy= "increment")

@Column(name = "id", nullable = false)
private Integer id;

@Column(name = "name", nullable = false)
private String name;

@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE,     CascadeType.PERSIST})
@JoinColumn(name = "id_switch", nullable = false)
private Switch idSwitch;

@Column(name = "status", nullable = false)
private String status;

@Column(name = "last_time_up", nullable = false)
private Date lastTimeUp;

@Column(name = "type", nullable = false)
private Integer type;

public Port (String name, Switch idSwitch, String status, Date lastTimeUp, Integer type) {
this.name = name;
this.idSwitch = idSwitch;
this.status = status;
this.lastTimeUp = lastTimeUp;
this.type = type;
}

public Integer getId() {
return id;
}

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

public String getName() {
return name;
}

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

public Switch getIdSwitch() {
return idSwitch;
}

public void setIdSwitch(Switch idSwitch) {
this.idSwitch = idSwitch;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public Date getLastTimeUp() {
return lastTimeUp;
}

public void setLastTimeUp(Date lastTimeUp) {
this.lastTimeUp = lastTimeUp;
}

@Override
public boolean equals(Object obj) {
if (obj == this)
    return true;
if (obj == null || obj.getClass() != this.getClass())
    return false;
Port port = (Port) obj;
return port.getId().equals(this.getId());
}

@Override
public int hashCode() {
return this.getId() * 31;
}

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

public Integer getType() {
return type;
}

public void setType(Integer type) {
this.type = type;
}
}

日志:

2019-08-22 11:26:23.811  INFO 5456 --- [           main] Main.TestMain                            
: Starting TestMain on ws507 with PID 5456     
(C:\Users\NetisovGA\IdeaProjects\testPing\target\classes started by netisovga 
in     C:\Users\NetisovGA\IdeaProjects\testPing)
2019-08-22 11:26:23.848  INFO 5456 --- [           main] Main.TestMain                            
: No active profile set, falling back to default profiles: default
2019-08-22 11:26:26.259  INFO 5456 --- [           main] 
.s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data 
repositories in DEFAULT mode.
2019-08-22 11:26:26.407  INFO 5456 --- [           main] 
.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository 
scanning in 113ms. Found 2 repository interfaces.
2019-08-22 11:26:29.227  WARN 5456 --- [           main] 
s.c.a.AnnotationConfigApplicationContext : Exception encountered during 
context initialization - cancelling refresh attempt: 
org.springframework.beans.factory.BeanCreationException: Error creating     bean 
with name 'entityManagerFactory' defined in class path resource 
[SpringDataComponents/config/DataConfig.class]: Invocation of init method 
failed; nested exception is java.lang.NullPointerException
2019-08-22 11:26:29.252  INFO 5456 --- [           main] 
ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run 
your application with 'debug' enabled.
2019-08-22 11:26:29.265 ERROR 5456 --- [           main] 
o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean 
with name 'entityManagerFactory' defined in class path resource 
[SpringDataComponents/config/DataConfig.class]: Invocation of init method 
failed; nested exception is java.lang.NullPointerException
    at     org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:139) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at Main.TestMain.main(TestMain.java:19) [classes/:na]
Caused by: java.lang.NullPointerException: null
at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher$DataSourceSchemaCreatedPublisher.getPersistenceProviderRootPackage(DataSourceInitializedPublisher.java:168) ~[spring-boot-autoconfigure-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:335) ~[spring-orm-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
... 14 common frames omitted


Process finished with exit code 1

我希望保存在数据库端口实体中,但只是我得到了它的空表。我认为这是 Spring Boot 运行的问题,但我是 Spring 新手,所以无法理解出了什么问题......

最佳答案

DataSourceSchemaCreatedPublisher ,其中NullPointerException发生时,将各种调用委托(delegate)给 JpaVendorAdapter它是从 LocalContainerEntityManagerFactoryBean 获得的。您正在配置自己的LocalContainerEntityManagerFactoryBean而不是依赖 Spring Boot 的自动配置并且不配置其 JpaVendorAdapter 。结果是null和一个 NullPointerException发生。

您的配置中有一行设置 JpaVendorAdapter但您已将其注释掉:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setDataSource(dataSource());
    entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
    entityManagerFactoryBean.setPackagesToScan(env.getRequiredProperty(PROP_ENTITYMANAGER_PACKAGES_TO_SCAN));
    // entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
    entityManagerFactoryBean.setJpaProperties(getHibernateProperties());

    return entityManagerFactoryBean;
}

取消注释该行应该可以解决您的问题:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setDataSource(dataSource());
    entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
    entityManagerFactoryBean.setPackagesToScan(env.getRequiredProperty(PROP_ENTITYMANAGER_PACKAGES_TO_SCAN));
    entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
    entityManagerFactoryBean.setJpaProperties(getHibernateProperties());

    return entityManagerFactoryBean;
}

更一般地说,我建议检查您的配置以及 Spring Boot 可以为您自动配置的内容。您的大部分配置都可以删除,以支持 Boot 和 application.properties 中的一些条目。文件。

关于java - Spring boot 无法运行,但服务 UTest 运行良好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57607374/

相关文章:

java - RMI over SSL,如何将信任库和 keystore 集成到应用程序中?

java - 从 Eclipse 部署到 Glassfish,不包含类

java - XIncludeAwareParserConfiguration 与 XMLParserConfiguration 不兼容

java - 如何正确使用MockMvc在Junit中测试post方法?

spring - Rest 自定义 HTTP 消息转换器 Spring Boot 1.2.3

java - 如何在 Spring Data JPA 中查找具有 OneToMany 关系的 cortege

java - save() 性能 - saveAndFlush() 会更好吗?

java - ByteBuffer分配直接示例

java - AfterReturning 注释不适用于特定方法结构

java - JPA 事务 - CrudRepository #save(List) 未回滚