LAZY无法正常工作

LAZY无法正常工作

好吧,这个标题有很多问题,但是没有一个答案正确或者与我的名字不完全相同。

我有两个实体:

人:

@Entity
@Table(name = "Person")
@Inheritance(strategy = InheritanceType.JOINED)
@Access(AccessType.FIELD)
public class Person {

    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "firstname")
    private String firstName;

    @Column(name = "lastname", length = 100, nullable = false, unique = false)
    private String lastName;

    @OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.MERGE, mappedBy="owner")
    private Set<Car> cars;

    public Long getId() {

        return id;
    }

    public void setId(Long id) {

        this.id = id;
    }

    public String getFirstName() {

        return firstName;
    }

    public void setFirstName(String firstName) {

        this.firstName = firstName;
    }

    public String getLastName() {

        return lastName;
    }

    public void setLastName(String lastName) {

        this.lastName = lastName;
    }

    public Set<Car> getCars() {

        return cars;
    }

    public void setCars(Set<Car> cars) {

        this.cars = cars;
    }

    @Override
    public String toString() {

        return String.format("(%d, %s, %s)",id, firstName, lastName);
    }
}


和汽车:

@Entity
@Table(name = "Car")
@Inheritance(strategy = InheritanceType.JOINED)
@Access(AccessType.FIELD)
public class Car {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.MERGE)
    @JoinColumn(name="id_person", columnDefinition="BIGINT")
    private Person owner;

    @Column(name="name")
    private String name;

    @Column(name="model")
    private String model;

    public Long getId() {

        return id;
    }

    public void setId(Long id) {

        this.id = id;
    }

    public Person getOwner() {

        return owner;
    }

    public void setOwner(Person owner) {

        this.owner = owner;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {

        this.name = name;
    }

    public String getModel() {

        return model;
    }

    public void setModel(String model) {

        this.model = model;
    }

    @Override
    public String toString() {

        return String.format("(%d, %s, %s, %s)", id, name, model, owner);
    }
}


另外,我在Mysql数据库中的id_person列的Person和Car表之间定义了一个外键约束。

我的persistence.xml文件如下:

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
 http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">

    <persistence-unit name="PersistenceUnit" transaction-type="RESOURCE_LOCAL">

        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <properties>
          <!-- Configuring JDBC properties -->
          <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/hibernatedb" />
          <property name="javax.persistence.jdbc.user" value="root" />
          <property name="javax.persistence.jdbc.password" value="DA_PASSWORD" />
          <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />

          <!-- Hibernate properties -->
          <property name="hibernate.show_sql" value="true" />
          <property name="hibernate.format_sql" value="true" />
          <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
          <property name="hibernate.hbm2ddl.auto" value="validate" />

          <!-- Configuring Connection Pool -->
          <property name="hibernate.c3p0.min_size" value="5" />
          <property name="hibernate.c3p0.max_size" value="20" />
          <property name="hibernate.c3p0.timeout" value="500" />
          <property name="hibernate.c3p0.max_statements" value="50" />
          <property name="hibernate.c3p0.idle_test_period" value="2000" />
        </properties>
    </persistence-unit>
</persistence>


在我的代码内,我尝试使用Criteria查询选择Cars,如下所示:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Car> q = cb.createQuery(Car.class);
Root<Car> root = q.from(Car.class);

q.select(root);


当我得到结果并打印时

TypedQuery<Car> typedQuery = entityManager.createQuery(q);
List<Car> cars = typedQuery.getResultList();
log.info("*****************************{}", cars);


令我惊讶的是,它打印:

*****************************[(1, Hiundai, 2016, (1, Homer1530962140, Simpson)), (2, Benz, 2016, (1, Homer1530962140, Simpson)), (3, Benz,
2017, (2, Homer12935192, Simpson))]


这意味着对于每一辆汽车,车主们也都非常热心!

这是数据库查询日志:

2017-02-17T14:02:58.324926Z   391 Query /* mysql-connector-java-5.1.13 ( Revision: ${bzr.revision-id} ) */SELECT @@session.auto_increment_increment
2017-02-17T14:02:58.325405Z   391 Query SHOW COLLATION
2017-02-17T14:02:58.335552Z   391 Query SET NAMES latin1
2017-02-17T14:02:58.335772Z   391 Query SET character_set_results = NULL
2017-02-17T14:02:58.336160Z   391 Query SET autocommit=1
2017-02-17T14:02:58.336349Z   391 Query SET autocommit=0
2017-02-17T14:02:58.720821Z   391 Query SHOW FULL TABLES FROM `hibernatedb` LIKE 'Car'
2017-02-17T14:02:58.724527Z   391 Query SHOW FULL TABLES FROM `hibernatedb` LIKE 'Car'
2017-02-17T14:02:58.725337Z   391 Query SHOW FULL COLUMNS FROM `Car` FROM `hibernatedb` LIKE '%'
2017-02-17T14:02:58.729899Z   391 Query SHOW FULL TABLES FROM `hibernatedb` LIKE 'Person'
2017-02-17T14:02:58.730468Z   391 Query SHOW FULL TABLES FROM `hibernatedb` LIKE 'Person'
2017-02-17T14:02:58.730887Z   391 Query SHOW FULL COLUMNS FROM `Person` FROM `hibernatedb` LIKE '%'
2017-02-17T14:02:59.022835Z   391 Query select car0_.id as id1_0_, car0_.model as model2_0_, car0_.name as name3_0_, car0_.id_person as id_perso4_0_ from Car car0_
2017-02-17T14:02:59.041016Z   391 Query SHOW WARNINGS
2017-02-17T14:02:59.045266Z   391 Query select person0_.id as id1_1_0_, person0_.firstname as firstnam2_1_0_, person0_.lastname as lastname3_1_0_ from Person person0_ where person0_.i
d=1
2017-02-17T14:02:59.059184Z   391 Query SHOW WARNINGS
2017-02-17T14:02:59.064163Z   391 Query select person0_.id as id1_1_0_, person0_.firstname as firstnam2_1_0_, person0_.lastname as lastname3_1_0_ from Person person0_ where person0_.i
d=2
2017-02-17T14:02:59.065827Z   391 Query SHOW WARNINGS
2017-02-17T14:02:59.070262Z   391 Query rollback
2017-02-17T14:02:59.070468Z   391 Quit


很明显,发出了一个单独的查询以获取“人员”信息,而我似乎在我的代码中却没有问过这样的事情。

为什么会这样呢?

最佳答案

在将汽车转换为字符串时,您要求所有者信息。

@Override
public String toString() {

    return String.format("(%d, %s, %s, %s)", id, name, model, owner);
}


那时,它必须检索所有者以执行您的toString()。

关于java - JPA/hibernate FetchType.LAZY无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42304805/

10-10 10:54