那麼,這個標題有很多問題,但沒有一個有正確的答案,或者他們不完全一樣。JPA /休眠FetchType.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列
我的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>
裏面我的代碼,我儘量選擇使用標準查詢汽車如下:
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
這是很明顯的,一個單獨的查詢是爲了獲得個人信息,而我似乎沒有問這樣的事情在我的代碼。
這是怎麼發生的?
謝謝@John Holmer。我自己正在考慮這部分代碼,但說實話,我很難理解JPA如何能夠檢測訪問實體提交的內容並基於此創建查詢。 – madz