@Entity  
public class Person {   
  
    private Integer per_Id;   
  
    private String per_name;   
  
    private IDCard idCard;   
  
    @Id  
    @GeneratedValue(strategy = GenerationType.AUTO)   
    public Integer getPer_Id() {   
        return per_Id;   
    }   
  
    public void setPer_Id(Integer per_Id) {   
        this.per_Id = per_Id;   
    }   
  
    @Column(nullable = false)   
    public String getPer_name() {   
        return per_name;   
    }   
       
    public void setPer_name(String per_name) {   
        this.per_name = per_name;   
    }   
       
    @OneToOne(optional=false,cascade={CascadeType.ALL})   
    @JoinColumn(name="car_id")   
    public IDCard getIdCard() {   
        return idCard;   
    }   
  
    public void setIdCard(IDCard idCard) {   
        this.idCard = idCard;   
    }   
}  @Entity  
public class IDCard {   
  
    private Integer car_id;   
  
    private String car_no;   
       
    private Person person;   
       
    @Id  
    @GeneratedValue(strategy=GenerationType.AUTO)   
    public Integer getCar_id() {   
        return car_id;   
    }   
  
    public void setCar_id(Integer car_id) {   
        this.car_id = car_id;   
    }   
       
    @Column(nullable=false)   
    public String getCar_no() {   
        return car_no;   
    }   
  
    public void setCar_no(String car_no) {   
        this.car_no = car_no;   
    }   
       
    @OneToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},mappedBy="idCard")   
    public Person getPerson() {   
        return person;   
    }   
  
    public void setPerson(Person person) {   
        this.person = person;   
    }   
  
}  @Test
 public void query() {
 EntityManagerFactory factory = Persistence
 .createEntityManagerFactory("demo");
 EntityManager em = factory.createEntityManager();
 Person person=em.find(Person.class, 1);    //这里为什么会执行2遍数据库查询呢?  请问哪里还应该配置? 

解决方案 »

  1.   

    Hibernate: select person0_.per_Id as per1_0_1_, person0_.car_id as car3_0_1_, person0_.per_name as per2_0_1_, idcard1_.car_id as car1_1_0_, idcard1_.car_no as car2_1_0_ from Person person0_ inner join IDCard idcard1_ on person0_.car_id=idcard1_.car_id where person0_.per_Id=?
    Hibernate: select person0_.per_Id as per1_0_1_, person0_.car_id as car3_0_1_, person0_.per_name as per2_0_1_, idcard1_.car_id as car1_1_0_, idcard1_.car_no as car2_1_0_ from Person person0_ inner join IDCard idcard1_ on person0_.car_id=idcard1_.car_id where person0_.car_id=?    查询的执行语句怎样的! 是2遍呀   
    但是我反过来查 IDCard  就只有1遍  为什么呀?
      

  2.   

    根据你的SQL语句分析,Hibernate所做的操作是先根据per_id查出card_id,然后在根据card_id查询得到person。你把 @OneToOne(cascade{CascadeType.MERGE,CascadeType.REFRESH},mappedBy="idCard")中的CascadeType.MERGE去掉。然后在person和idcard的映射中加上fetch = FetchType.LAZY,在试试。
      

  3.   

    按照 楼上的做了以后,值查询Person person=em.find(Person.class, 1);  确实只有一句了但是 person.getIdCard().getCar_no();  当获取关联对象属性的时候 出现了3条语句 
    Hibernate: select person0_.per_Id as per1_0_0_, person0_.car_id as car3_0_0_, person0_.per_name as per2_0_0_ from Person person0_ where person0_.per_Id=?
    Hibernate: select idcard0_.car_id as car1_1_0_, idcard0_.car_no as car2_1_0_ from IDCard idcard0_ where idcard0_.car_id=?
    Hibernate: select person0_.per_Id as per1_0_0_, person0_.car_id as car3_0_0_, person0_.per_name as per2_0_0_ from Person person0_ where person0_.car_id=?
      

  4.   

    难道这个就是JPA中N+1问题? 
      

  5.   

     person.getIdCard().getCar_no(); 
    这句的确是要3条查询语句:
    首先,得到person对象就要通过per_id查询得到person,此第一次。
    其次,得到person的IDcard时,会执行一次通过person的card_id去查询IDcard,但是由于你没有在IDcard的一方加入fetch = FetchType.LAZY,Hibernate又将person加载进来,即又执行了一次查询,这里有2次。
    所以一共3次。
    一般在配置Hibernate的对象时,无论映射文件还是写注解,在关联的双方都加上fetch = FetchType.LAZY,另外Session的管理要配置好,不然懒加载执行的时候会报Session关闭的异常。
      

  6.   

    我在IDcard的一方也加入fetch = FetchType.LAZY呀,但是还是3条语句,你试试。
      

  7.   

    能看下完整的Test的代码吗?加入懒加载的话没道理会将全部的都加载进来的。
      

  8.   

    @Test
     public void query() {
     EntityManagerFactory factory = Persistence
     .createEntityManagerFactory("demo");
     EntityManager em = factory.createEntityManager();
     Person person=em.find(Person.class,2);
      //String name=person.getPer_name();
      person.getIdCard().getCar_no();
     //System.out.println(person.getVisible());
    // System.out.println(iCard.getPerson().getPer_name());
    //System.out.println(n);
     //System.out.println(name);
     em.close();
     factory.close();
    }
    }就是很简单的怎样呀!