2017-06-11 57 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); 
}