我理解成语是将你的成员变量定义为私有和自动创建getter和setter,并在hibernate代码中使用它。
但我很好奇,如果我没有定义getter / setter,它是否会起作用,并直接引用成员变量/属性(现在公开)。
在下面的代码App.java中,行
” System.out.println(“loaded”+ emp2.account.getAccountNumber()); “
这里emp2是一个持久的obj(从db加载),我实际上可以直接引用“account”成员,但不知何故,当我直接引用account.accountNumber时,它给了我一个null,所以我不得不使用帐号.getAccountNumber();
那么为什么这两个案例会给出不同的结果呢?
---不知怎的,我似乎已经获得了“直接成员访问”,可以在所有情况下工作。但现在我找不到。
由于 杨
文件:App.java
package yy.learnhibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* Hello world!
*
*/
public class App {
public static void main(String[] args) {
SessionFactory factory = new Configuration().configure().buildSessionFactory();
AccountEntity acct;
EmployeeEntity emp;
acct = new AccountEntity();
acct.accountNumber= "fakeNumber";
emp = new EmployeeEntity();
emp.firstName = "f";
emp.account = acct;
Session session1 = factory.openSession();
session1.beginTransaction();
session1.save(acct);
session1.save(emp);
emp = new EmployeeEntity();
emp.firstName = "f2";
emp.account = acct;
session1.save(emp);
//
session1.getTransaction().commit();
session1.close();
session1 = factory.openSession();
session1.beginTransaction();
AccountEntity acct2 = (AccountEntity) session1.load(AccountEntity.class, 1);
EmployeeEntity emp2 = (EmployeeEntity) session1.get(EmployeeEntity.class, 1);
System.out.println("loaded " + emp2.account.getAccountNumber());
for (EmployeeEntity e : acct2.getEmployee()) {
System.out.println("seen employee" + e.firstName);
}
acct2.setAccountNumber("changed ");
// session1.update(acct2);
session1.getTransaction().commit();
}
}
文件:AccountEntity.java
package yy.learnhibernate;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "Account")
public class AccountEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1770939417652939285L;
@Id
@Column(name = "ID", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer accountId;
@Column
public String accountNumber;
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
@OneToMany(mappedBy = "account")
// @Transient
// We will define the association here
public Set<EmployeeEntity> employee = new HashSet<EmployeeEntity>();
public Integer getAccountId() {
return accountId;
}
public void setAccountId(Integer accountId) {
this.accountId = accountId;
}
public Set<EmployeeEntity> getEmployee() {
return employee;
}
public void setEmployee(Set<EmployeeEntity> employee) {
this.employee = employee;
}
//
// // Getters and Setters are not shown for brevity
}
EmployeeEntity.java
package yy.learnhibernate;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = "Employee")
public class EmployeeEntity implements Serializable {
private static final long serialVersionUID = -1798070786993154676L;
@Id
@Column(name = "ID", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer employeeId;
@Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
public String firstName;
@ManyToOne
// We will define the association here
public AccountEntity account;
public Integer getEmployeeId() {
return employeeId;
}
public void setEmployeeId(Integer employeeId) {
this.employeeId = employeeId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public AccountEntity getAccount() {
return account;
}
public void setAccount(AccountEntity account) {
this.account = account;
}
// Getters and Setters are not shown for brevity
}
答案 0 :(得分:0)
因为持久性提供程序(Hibernate,TopLink等)不直接使用该类,所以它们会创建proxy,因此当您尝试访问这些方法时,它们会在内部使用此代理加载权限数据,这意味着他们不仅仅使用访问成员的类,他们可以解决延迟加载或其他类型的东西。 对于Java EE注入部分也是如此,它们总是使用代理来模拟相同的类但添加一些特定的行为,因此反射使用方法而不是代理的变量
答案 1 :(得分:0)
实际上,我找到了答案,原因是由于load()和get()的不同。后者给出了一个真正的对象impl,而第一个给出了一个代理。当你使用get()时,即使直接的属性成员访问也被AOP捕获,并且添加了必要的额外操作(保存到db,扩展到关联等)