JPA引用实体构造函数中的其他实体

时间:2014-07-09 10:26:54

标签: java jpa

在我的数据库表Attribute中,我将首先加载一个数据列表。每次,当我想要保留MyAttribute的新记录时,我需要首先搜索表Attribute,然后在插入表MyAttribute之前从表Attribute中选择适当的记录。

@Entity
class MyAttribute{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @ManyToOne(targetEntity = Attribute.class)
    @JoinColumn(name="attribute_id", referencedColumnName="id")
    Attribute detail;

    private String greet;

    public MyAttribute(){
        this.greet = "Hello World.";
        this.detail = new MyDbLayer().selectAttributeDetail("first"); //Error is thrown here.
    }

    //getter & setter
}

@Entity
class Attribute{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Index(name = "name_index")
    @Column(unique=true )
    private String name;

    //getter & setter
}

class MyDbLayer{
    private EntityManagerFactory emf;

    public MyDbLayer() {
        emf = Persistence.createEntityManagerFactory("MyPu");
    }

    public Attribute selectAttributeDetail(String name) {
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();

        Query queryGetAttribute = em.createQuery("select a from Attribute a where a.name = :attributeName");

        List<AttributeDescription> attributeDescList = queryGetAttribute.setParameter("attributeName", name).getResultList();

        AttributeDescription tempAttribute = null;

        if (!attributeDescList.isEmpty()) {
            tempAttribute = (AttributeDescription) attributeDescList.get(0);
        }

        em.clear();
        em.close();

        return tempAttribute;
    }
}

我不确定为什么我继续接收错误,如:

  

javax.persistence.PersistenceException:[PersistenceUnit:MyPu]无法使用   构建EntityManagerFactory

     

引起:org.hibernate.MappingException:无法获取构造函数   for org.hibernate.persister.entity.SingleTableEntityPersister

     

引起:org.hibernate.InstantiationException:无法实例化   测试对象

P.S。这不是我正在研究的真实代码,但结构或多或少相同。

2 个答案:

答案 0 :(得分:3)

如何为Attribute创建第二个构造函数?

public MyAttribute(){
    this.greet = "Hello World.";
    // this.detail = new MyDbLayer().selectAttributeDetail("first"); //Error is thrown here.
}

public MyAttribute(Attribute detail){
    this.greet = "Hello World.";
    this.detail = detail;
}

jpa也使用默认构造函数来加载持久化对象。这可能会导致意外行为

答案 1 :(得分:0)

JPA模型中不能从实体访问EntityManager。它可以完成,但根据实现情况,它可以有不同的行为。

在你的情况下,从no args构造函数访问EntityManager绝不是一个好主意。因为这是EntityManager在加载实体时使用的构造函数。因此,每次MyAttribute加载EntityManager时,您都会尝试创建antoher EntityManager来初始化detail关系,该关系将被第一个EntityManager使用覆盖它从数据库加载的值。

通常你应该有一个服务层,可以访问管理你的JPA实体的EntityManager