2017-06-11 56 views
1

我尝试将PersonManager及其列表存储到数据库中。未存储在数据库中的列表 - 休眠弹簧

其实一切似乎都很顺利,没有错误,PersonManager正确存储在数据库中。但不是它的列表

但是,只要我访问数据库并尝试迭代保存在PersonManager列表中的人员,返回的列表始终为空。

我使用Spring-Boot,Hibernate并使用H2-Filebased数据库。日志在这篇文章的末尾,对于看看发生了什么很重要。

这里my Repo

@Entity 
public class Person { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    final String name; 
    @ManyToOne 
    private PersonManager personManager; 

    public PersonManager getPersonManager() { 
     return personManager; 
    } 

    public void setPersonManager(PersonManager personManager) { 
     this.personManager = personManager; 
    } 

    public String getName() { 
     return name; 
    } 

    public Long getId() { 

     return id; 
    } 

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

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     Person person = (Person) o; 

     if (!id.equals(person.id)) return false; 
     return name != null ? name.equals(person.name) : person.name == null; 
    } 

    @Override 
    public int hashCode() { 
     int result = id.hashCode(); 
     result = 31 * result + (name != null ? name.hashCode() : 0); 
     return result; 
    } 

    public Person(String name) { 
     this.name = name; 
    } 
} 

的PersonManager

@Entity 
public class PersonManager { 

    @OneToMany(mappedBy = "personManager", fetch = FetchType.EAGER) 
    private final List<Person> personList = new LinkedList<>(); 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    Long id; 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     PersonManager that = (PersonManager) o; 

     if (!id.equals(that.id)) return false; 
     return personList != null ? personList.equals(that.personList) : that.personList == null; 
    } 

    @Override 
    public int hashCode() { 
     int result = id.hashCode(); 
     result = 31 * result + (personList != null ? personList.hashCode() : 0); 
     return result; 
    } 

    public Long getId() { 
     return id; 
    } 

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

    public List<Person> getPersonList() { 
     return personList; 
    } 

    public void addPerson(Person person) { 
     personList.add(person); 
    } 

    public void removePerson(Person person) { 
     personList.remove(person); 
    } 
} 

HibernateApplication

@SpringBootApplication 
public class HibernateApplication { 


    private static final Logger log = LoggerFactory.getLogger(HibernateApplication.class); 

    public static void main(String[] args) { 
     SpringApplication.run(HibernateApplication.class); 
    } 


    @Bean 
    public CommandLineRunner addObservables(ObserveableRepository repository) { 
     return (args) -> { 
      useObserver(repository); 

      // fetch all customers 
      log.info("PersonManager found with findAll():"); 
      log.info("-------------------------------"); 
      for (PersonManager personManager : repository.findAll()) { 
       log.info("ListContent: " + personManager.getPersonList().size()); 
      } 
      log.info(""); 

     }; 
    } 

    private void usePersonManager(PersonManagerRepo repository) { 
     PersonManager personManager = new PersonManager(); 
     personManager.addPerson(new Person("Hans")); 
     personManager.addPerson(new Person("Peter")); 
     personManager.addPerson(new Person("Max")); 
     log.info("List.size() : " + personManager.getPersonList().size()); 
     repository.save(personManager); 
    } 


    /** 
    * Start internal H2 server so we can query the DB from IDE 
    * 
    * @return H2 Server instance 
    * @throws SQLException 
    */ 
    /* 
    @Bean(initMethod = "start", destroyMethod = "stop") 
    public Server h2Server() throws SQLException { 
     return Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort", "9092"); 
    } 
    */ 
} 

PersonManagerRepo

application.properties

spring.datasource.url=jdbc:h2:file:~/test2;DB_CLOSE_ON_EXIT=FALSE;AUTO_RECONNECT=TRUE 
spring.datasource.username=admin 
spring.datasource.password=password 
spring.datasource.driver-class-name=org.h2.Driver 
spring.jpa.show-sql=true 
spring.jpa.hibernate.ddl-auto=update 
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect 

我记录的大小和,你可以在下面的列表中的元素。第一次运行时,元素存在。重建后他们走了。

2017-06-12 17:12:26.160 INFO 3252 --- [   main] c.e.hibernate.HibernateApplication  : No active profile set, falling back to default profiles: default 
2017-06-12 17:12:26.185 INFO 3252 --- [   main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot[email protected]4516af24: startup date [Mon Jun 12 17:12:26 CEST 2017]; root of context hierarchy 
2017-06-12 17:12:26.948 INFO 3252 --- [   main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$b98d9ce8] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 
2017-06-12 17:12:27.156 INFO 3252 --- [   main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http) 
2017-06-12 17:12:27.162 INFO 3252 --- [   main] o.apache.catalina.core.StandardService : Starting service Tomcat 
2017-06-12 17:12:27.163 INFO 3252 --- [   main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.14 
2017-06-12 17:12:27.212 INFO 3252 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]  : Initializing Spring embedded WebApplicationContext 
2017-06-12 17:12:27.212 INFO 3252 --- [ost-startStop-1] o.s.web.context.ContextLoader   : Root WebApplicationContext: initialization completed in 1029 ms 
2017-06-12 17:12:27.284 INFO 3252 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 
2017-06-12 17:12:27.286 INFO 3252 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 
2017-06-12 17:12:27.287 INFO 3252 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 
2017-06-12 17:12:27.287 INFO 3252 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*] 
2017-06-12 17:12:27.287 INFO 3252 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] 
2017-06-12 17:12:27.506 INFO 3252 --- [   main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default' 
2017-06-12 17:12:27.513 INFO 3252 --- [   main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [ 
    name: default 
    ...] 
2017-06-12 17:12:27.546 INFO 3252 --- [   main] org.hibernate.Version     : HHH000412: Hibernate Core {5.0.12.Final} 
2017-06-12 17:12:27.546 INFO 3252 --- [   main] org.hibernate.cfg.Environment   : HHH000206: hibernate.properties not found 
2017-06-12 17:12:27.547 INFO 3252 --- [   main] org.hibernate.cfg.Environment   : HHH000021: Bytecode provider name : javassist 
2017-06-12 17:12:27.567 INFO 3252 --- [   main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final} 
2017-06-12 17:12:27.619 INFO 3252 --- [   main] org.hibernate.dialect.Dialect   : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect 
2017-06-12 17:12:27.858 INFO 3252 --- [   main] org.hibernate.tuple.PojoInstantiator  : HHH000182: No default (no-argument) constructor for class: com.example.hibernate.Person (class must be instantiated by Interceptor) 
2017-06-12 17:12:27.901 INFO 3252 --- [   main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export 
Hibernate: drop table person if exists 
Hibernate: drop table person_manager if exists 
Hibernate: create table person (id bigint generated by default as identity, name varchar(255), person_manager_id bigint, primary key (id)) 
Hibernate: create table person_manager (id bigint generated by default as identity, primary key (id)) 
Hibernate: alter table person add constraint FKmyv6vk7htrqtbt7ji7rngwgh2 foreign key (person_manager_id) references person 
2017-06-12 17:12:27.912 INFO 3252 --- [   main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete 
2017-06-12 17:12:27.928 INFO 3252 --- [   main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 
2017-06-12 17:12:28.173 INFO 3252 --- [   main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot[email protected]4516af24: startup date [Mon Jun 12 17:12:26 CEST 2017]; root of context hierarchy 
2017-06-12 17:12:28.208 INFO 3252 --- [   main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 
2017-06-12 17:12:28.209 INFO 3252 --- [   main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 
2017-06-12 17:12:28.223 INFO 3252 --- [   main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 
2017-06-12 17:12:28.223 INFO 3252 --- [   main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 
2017-06-12 17:12:28.241 INFO 3252 --- [   main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 
2017-06-12 17:12:28.369 INFO 3252 --- [   main] o.s.j.e.a.AnnotationMBeanExporter  : Registering beans for JMX exposure on startup 
2017-06-12 17:12:28.398 INFO 3252 --- [   main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 
2017-06-12 17:12:28.400 INFO 3252 --- [   main] c.e.hibernate.HibernateApplication  : List.size() : 3 
Hibernate: insert into person_manager (id) values (null) 
2017-06-12 17:12:28.434 INFO 3252 --- [   main] c.e.hibernate.HibernateApplication  : Observables found with findAll(): 
2017-06-12 17:12:28.434 INFO 3252 --- [   main] c.e.hibernate.HibernateApplication  : ------------------------------- 
2017-06-12 17:12:28.446 INFO 3252 --- [   main] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory 
Hibernate: select personmana0_.id as id1_1_ from person_manager personmana0_ 
Hibernate: select personlist0_.person_manager_id as person_m3_0_0_, personlist0_.id as id1_0_0_, personlist0_.id as id1_0_1_, personlist0_.name as name2_0_1_, personlist0_.person_manager_id as person_m3_0_1_ from person personlist0_ where personlist0_.person_manager_id=? 
2017-06-12 17:12:28.493 INFO 3252 --- [   main] c.e.hibernate.HibernateApplication  : ListContent: 0 
2017-06-12 17:12:28.493 INFO 3252 --- [   main] c.e.hibernate.HibernateApplication  : 
2017-06-12 17:12:28.494 INFO 3252 --- [   main] c.e.hibernate.HibernateApplication  : Started HibernateApplication in 2.47 seconds (JVM running for 2.718) 

你能告诉我如何解决这个问题吗?

谢谢:)

+0

当您启动应用程序时,您是否看到hibernate在日志文件中执行任何ddl?像创建/删除? – xyz

+0

你是对的它只能插入,但它不会创建一个表(我只是读了我在这里复制的控制台输出)为什么?由于我没有收到任何错误消息,我不知道如何解决该问题 – AnnaKlein

+0

检查文件是否存在 – xyz

回答

1

这里的关键是,你要设置一个双向的关系,要级联的操作。所以第一个改变是在PersonManager实体的@OneToMany注解中添加级联。

@OneToMany(mappedBy = "personManager", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 

然后,您需要记住,当您创建新的子元素时,您需要将它们与其父项关联。

为了做到这一点首先添加一个新的构造函数Person实体:

public Person(String name, PersonManager personManager) { 
    this.name = name; 
    this.personManager = personManager; 
} 

注意您可能还需要添加默认的公共构造使Hibernate并不需要使用的拦截器。如果您仔细观察日志,您可能会在当前实施中看到日志中的警告。

public Person() { 
    this.name = null; 
} 

最后更改您的HibernateApplication类。在创建Person对象时,调用新的构造函数并传递Parent的实例。您的其他选项是创建每个Person对象,然后调用传递PersonManager实例中的每个对象的setPersonManager方法。

private void useObserver(ObserveableRepository repository) { 
    PersonManager personManager = new PersonManager(); 
    personManager.addPerson(new Person("Hans", personManager)); 
    personManager.addPerson(new Person("Peter", personManager)); 
    personManager.addPerson(new Person("Max", personManager)); 
    log.info("List.size() : " + personManager.getPersonList().size()); 
    repository.save(personManager); 
}