列表未存储在数据库中 - Hibernate Spring

时间:2017-06-11 17:50:39

标签: java hibernate spring-boot

我尝试将PersonManager及其List存储到数据库中。

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

但是一旦我访问数据库并尝试迭代保存在PersonManager列表中的人员,返回的List总是为空。

我使用Spring-Boot,Hibernate并拥有一个基于H2文件的数据库。日志就在这篇文章的最后,对于了解情况很重要。

此处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

public interface PersonManagerRepo extends CrudRepository<PersonManager, Long> {

}

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.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@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.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@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)

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

谢谢:)

1 个答案:

答案 0 :(得分:1)

这里的关键是你要建立一个双向关系,你想要级联操作。因此,第一个更改是在PersonManager实体上为@OneToMany注释添加级联。

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

然后你需要记住,当你创建新的Child元素时,你需要将它们与它们的父元素相关联。

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

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

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

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

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

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