好吧,这个标题有很多问题,但是没有一个答案正确或者与我的名字不完全相同。
我有两个实体:
人:
@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/