我可以通过属性成员(而不是访问者)访问hibernate持久化对象吗?

时间:2015-09-17 19:27:55

标签: hibernate aop

我理解成语是将你的成员变量定义为私有和自动创建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
}

2 个答案:

答案 0 :(得分:0)

因为持久性提供程序(Hibernate,TopLink等)不直接使用该类,所以它们会创建proxy,因此当您尝试访问这些方法时,它们会在内部使用此代理加载权限数据,这意味着他们不仅仅使用访问成员的类,他们可以解决延迟加载或其他类型的东西。 对于Java EE注入部分也是如此,它们总是使用代理来模拟相同的类但添加一些特定的行为,因此反射使用方法而不是代理的变量

答案 1 :(得分:0)

实际上,我找到了答案,原因是由于load()和get()的不同。后者给出了一个真正的对象impl,而第一个给出了一个代理。当你使用get()时,即使直接的属性成员访问也被AOP捕获,并且添加了必要的额外操作(保存到db,扩展到关联等)