2015-09-17 64 views
0

我知道這個習慣用法是將你的成員變量定義爲private,並自動創建getter和setter,並在hibernate代碼中使用它。我可以通過屬性成員(而不是訪問器)訪問hibernate持久對象嗎?

但我只是好奇它是否會工作,如果我沒有定義getters/setters,並直接引用成員變量/屬性(現已公開)。

在下面的代碼App.java,線

「 的System.out.println(」 裝入 「+ emp2.​​account.getAccountNumber()); 」

這裏EMP2是持久obj(從數據庫加載),我實際上可以直接引用「帳戶」成員,但不知何故,當我直接引用account.accountNumber時,它給了我一個null,所以我不得不使用account.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

Becau如果持久化提供程序(Hibernate,TopLink等)不直接使用該類,則它們會創建一個proxy,因此當您嘗試訪問這些方法時,它們在內部使用此代理來加載正確的數據,這意味着它們會不只是使用訪問該成員的類,他們可以解析延遲加載或其他類型的東西。 同樣適用於Java EE注入部分,他們總是使用proxys模擬相同的類,但添加了一些特定的行爲,所以反射使用的方法而不是代理變量

+0

謝謝。我瞭解代理/ AOP部分。但我只是想知道爲什麼我能夠直接訪問emp2.​​account。據說它應該給我一個null,但在這種情況下,它確實拉了實際的對象(注意它不只是存儲在表中的account_id)。 –

0

實際上,我找到了答案,原因是由於負載()和get()的差異。後者給出了一個真實對象impl,而第一個給出了一個代理。當你使用get(),甚至直接屬性成員訪問也被AOP捕獲和必要的額外操作(保存到數據庫,擴展到關聯等)被添加

相關問題