使用现有父对象持久化子对象

use*_*560 4 hibernate jpa hibernate-mapping jpa-2.0

假设有两个具有ManyToOne关系的实体:

@Entity
public class A {
    private long code;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)   
    public long getCode() {
        return code;
    }

    public viod setCode(long code) {
        this.code = code;
    }

    // additional setters and getters
}

@Entity
public class B {
    private long code;
    private A a;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)   
    public long getCode() {
        return code;
    }

    public viod setCode(long code) {
        this.code = code;
    }   

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="acode", nullable=false)   
    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a
    }

    // additional setters and getters   
}
Run Code Online (Sandbox Code Playgroud)

作为业务流程的一部分,我有现有A对象的代码值,我需要插入新的B对象并将其与现有的A相关联.此代码工作正常:

// inject em
A a = em.find(A.class, code);
B b = new B();
b.setA(a);
em.persist(b);
Run Code Online (Sandbox Code Playgroud)

我的问题是"A a = em.find(A.class,code)"行.这看起来像是一个冗余查询,因为B表包含一个外键(acode).为了提高性能,我尝试使用现有代码值创建A对象:

A a = new A();
a.setCode(code);
B b = new B();
b.setA(a);
em.persist(b);
Run Code Online (Sandbox Code Playgroud)

但它不起作用.有什么方法可以避免不必要的查询吗?

axt*_*avt 5

有一种特殊的getReference()方法可以用来代替find()这种情况.它创建一个具有指定id的代理对象,而不发出queires.A保存时,数据库端的外键约束检查具有该id的存在性B.

A a = em.getReference(A.class, code);
B b = new B();
b.setA(a);
em.persist(b); 
Run Code Online (Sandbox Code Playgroud)