Hibernate通过一对一映射从两个表中获取数据

时间:2016-09-09 05:58:53

标签: hibernate spring-mvc hql

我有两张桌子' Person'和PersonDetail'。现在,我想从这些

中获取数据

使用HQL的两个表。

我应该怎么做?我应该编写单独的查询,如

this

链接,还是应该编写连接查询?

如何在一个页面上显示这两个表中的数据?

我的工作代码

/////////////////////////主要应用//////////////////// //////////

package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.web.SpringBootServletInitializer;

@SuppressWarnings("deprecation")
@SpringBootApplication
public class SpringBootWeb1Application extends SpringBootServletInitializer{

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

////////////////////////////////的IndexController ////////////// //////

package com.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class IndexController {
    @RequestMapping("/")
    String index(){
        return "index";
    }
}

//////////////////////// PersonController ///////////////////

package com.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;


import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


import com.model.Person;
import com.service.PersonService;

@Controller
public class PersonController {
    @Autowired
    private PersonService personService;

     @Autowired
        public void setPersonService(PersonService personService) {
            this.personService = personService;
        }


        @RequestMapping(value = "/persons", method = RequestMethod.GET)
        public String list(Model model){
            model.addAttribute("persons", personService.listAllPersons());

            return "persons";
        }


        @RequestMapping("person/{id}")
        public String showPerson(@PathVariable Integer id, Model model){
            model.addAttribute("person", personService.getPersonById(id));
            return "personshow";
        }


        @RequestMapping("person/edit/{id}")
        public String edit(@PathVariable Integer id, Model model){
            model.addAttribute("person", personService.getPersonById(id));
            return "personform";
        }


        @RequestMapping("person/new")
        public String newPerson(Model model){
            model.addAttribute("person", new Person());
            return "personform";
        }


        @RequestMapping(value = "person", method = RequestMethod.POST)
        public String saveProduct(Person person){
            personService.savePerson(person);
            return "redirect:/person/" + person.getId();
        }


        @RequestMapping("person/delete/{id}")
        public String delete(@PathVariable Integer id){
            personService.deletePerson(id);
            /*return "redirect:/products";*/
            return "personform";

        }


}

/////////////////////////////////人///////////// /////////////

package com.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Person {
     @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Integer id;
        private String name;
        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;
        }

}

///////////////////////////// PersonDetail ///////////////// ////////////

package com.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;


@Entity
@Table(name = "PersonDetail", catalog = "myschema")
public class PersonDetail {
    @Id
    @GeneratedValue
    private Integer id;
    private String address;
    private Integer age;

    @OneToOne(fetch=FetchType.LAZY)
    @PrimaryKeyJoinColumn
    private Person person;

    public PersonDetail(){}

    public PersonDetail(Integer id,String address,Integer age)
    {
        this.id=id;
        this.address=address;
        this.age=age;
    }

    @GenericGenerator(name = "generator", strategy = "foreign")
            @Id
            @GeneratedValue(generator = "generator")
            @Column(name = "id", unique = true, nullable = false)
    public Integer getId() {
        return id;
    }


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

    @Column(name = "address", nullable = false, length = 20)
    public String getAddress() {
        return address;
    }


    public void setAddress(String address) {
        this.address = address;
    }

    @Column(name = "age", nullable = false)
    public Integer getAge() {
        return age;
    }


    public void setAge(Integer age) {
        this.age = age;
    }
    @OneToOne(fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn
    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }


}

///////////////////////////// PersonRepository ///////////////// /////////////

package com.repository;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.model.Person;
@Repository
public interface PersonRepository extends CrudRepository<Person, Integer>{
}

////////////////////////// PersonDetailRepository //////////////////// /

package com.repository;

import org.springframework.data.repository.CrudRepository;

import com.model.PersonDetail;

public interface PersonDetailRepository extends CrudRepository<PersonDetail, Integer>{

}

///////////////////////////////服务/////////////// ////////

package com.service;

import com.model.Person;



public interface PersonService {
     Iterable<Person> listAllPersons();

        Person getPersonById(Integer id);

        Person savePerson(Person person);

        void deletePerson(Integer id);
}

/////////////////////////////// ServiceImpl /////////////// //////

package com.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.model.Person;
import com.repository.PersonRepository;
@Service
public class PersonServiceImpl implements PersonService{
    private PersonRepository personRepository;

      @Autowired
        public void setPersonRepository(PersonRepository personRepository) {
            this.personRepository = personRepository;
        }


    @Override
    public Iterable<Person> listAllPersons() {
        // TODO Auto-generated method stub
        return personRepository.findAll();
    }

    @Override
    public Person getPersonById(Integer id) {
        // TODO Auto-generated method stub
        return personRepository.findOne(id);
    }

    @Override
    public Person savePerson(Person person) {
        // TODO Auto-generated method stub
        return personRepository.save(person);
    }
     @Override
        public void deletePerson(Integer id) {
            personRepository.delete(id);

        }
}

////////////////////////的index.jsp //////////////////// /////////

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">

    <title>Spring Boot Example</title>
    <!-- <th:block th:include="fragments/headerinc :: head"></th:block> -->
</head>
<body>
<div class="container">
    <div th:fragment="header">
        <nav class="navbar navbar-default">
            <div class="container-fluid">
                <div class="navbar-header">
                    <a class="navbar-brand" href="#" th:href="@{/}">Home</a>
                    <ul class="nav navbar-nav">
                        <li><a href="#" th:href="@{/persons}">Persons</a></li>
                        <li><a href="#" th:href="@{/person/new}">Create Person</a></li>
                    </ul>

                </div>
            </div></nav></div>
<!-- <div class="container"> -->
   <!--  <th:block th:include="fragments/header :: header"></th:block> -->
</div>
</body>
</html>

///////////////////////// personform.jsp /////////////////// ////////

   <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">

    <title>Spring Boot Example</title>

     <th:block th:include="fragments/headerinc :: head"></th:block> 
</head>
<body>
<div class="container">
    <th:block th:include="fragments/header :: header"></th:block> 

    <h2>Person Details</h2>
    <div>
        <form class="form-horizontal" th:object="${person}" th:action="@{/person}" method="post">
            <input type="hidden" th:field="*{id}"/>

            <div class="form-group">
                <label class="col-sm-2 control-label">Person Id:</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" th:field="*{id}"/>
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-2 control-label">Name:</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" th:field="*{name}"/>
                </div>
            </div>
             <div class="form-group">
                <label class="col-sm-2 control-label">Address:</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" th:field="*{address}"/>
                </div>
            </div>
             <div class="form-group">
                <label class="col-sm-2 control-label">Age:</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" th:field="*{age}"/>
                </div>
            </div>

            <div class="row">
                <button type="submit" class="btn btn-default">Submit</button>
            </div>
        </form>
    </div>
</div>

</body>
</html>

/////////////////////////人///////////////////// /

   <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">

    <title>Spring Boot Example</title>

   <th:block th:include="fragments/headerinc :: head"></th:block> 
</head>
<body>
<div class="container">
    <!--/*/ <th:block th:include="fragments/header :: header"></th:block> /*/-->
    <div th:if="${not #lists.isEmpty(persons)}">
        <h2>Person List</h2>
        <table class="table table-striped">
            <tr>
                <th>Id</th>
                <th>Person Id</th>
                <th>Name</th>
                <th>Age</th>
                <th>Address</th>

                <th>View</th>
                <th>Edit</th>
                <th>Delete</th>
            </tr>
            <tr th:each="person : ${persons}">
                <td th:text="${person.id}"><a href="/person/${id}">Id</a></td>
                <td th:text="${person.id}">Person Id</td>
                <td th:text="${person.name}">description</td>
                <td th:text="${person.personDetail.address}">Address</td>
                <td th:text="${person.personDetail.age}">Age</td>
                <!--   <td th:text="${product.price}">price</td> -->
                <td><a th:href="${ '/person/' + person.id}">View</a></td>
                <td><a th:href="${'/person/edit/' + person.id}">Edit</a></td>
                <td><a th:href="${'/person/delete/' + person.id}">Delete</a></td>
            </tr>
        </table>

    </div>
</div>

</body>
</html>

////////////////////////// personshow //////////////////// /////////

    <!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">

    <title>Person Details</title>

    <th:block th:include="fragments/headerinc :: head"></th:block> 
</head>
<body>
<div class="container">
    <!--/*/ <th:block th:include="fragments/header :: header"></th:block> /*/-->

    <h2>Person Details</h2>
        <div>
            <form class="form-horizontal">
                <div class="form-group">
                    <label class="col-sm-2 control-label">Person Id:</label>
                    <div class="col-sm-10">
                        <p class="form-control-static" th:text="${person.id}">Person Id</p></div>
                </div>
                <div class="form-group">
                    <label class="col-sm-2 control-label">Name:</label>
                    <div class="col-sm-10">
                        <p class="form-control-static" th:text="${person.name}">name</p>
                    </div>
                </div>
                 <div class="form-group">
                    <label class="col-sm-2 control-label">Address:</label>
                    <div class="col-sm-10">
                        <p class="form-control-static" th:text="${person.personDetail.address}">address</p>
                    </div>
                </div>
                 <div class="form-group">
                    <label class="col-sm-2 control-label">Name:</label>
                    <div class="col-sm-10">
                        <p class="form-control-static" th:text="${person.personDetail.address}">age</p>
                    </div>
                </div>

            </form>
    </div>
</div>

</body>
</html>

堆栈跟踪:

2016-09-09 15:37:49.866 ERROR 3836 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unknown mappedBy in: com.model.Person.personDetail, referenced property unknown: com.model.PersonDetail.Person
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:851) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:313) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
    at com.SpringBootWeb1Application.main(SpringBootWeb1Application.java:12) [classes/:na]
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: com.model.Person.personDetail, referenced property unknown: com.model.PersonDetail.Person
    at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:154) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1655) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1623) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847) ~[hibernate-entitymanager-5.0.9.Final.jar:5.0.9.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874) ~[hibernate-entitymanager-5.0.9.Final.jar:5.0.9.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:338) ~[spring-orm-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373) ~[spring-orm-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362) ~[spring-orm-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
    ... 16 common frames omitted

1 个答案:

答案 0 :(得分:2)

String hql = "FROM PersonDetail pd JOIN pd.person";
        Query query = session.createQuery(hql);
        List<PersonDetail> personalDetailsList= query.list();

首先迭代上面的列表然后你可以获得如下的人员详细信息......

while()  // Iterate above list
{
    Person person=personalDetails.getPerson();
}