JPA实体创建 - 对象与“原始”

时间:2011-04-20 17:13:26

标签: java netbeans entity jpa-2.0 netbeans-6.9

我有一个关于实体创建的问题。说我有以下表格

create table "foo" (
  "id"          integer primary key,
  "name"        varchar
);

create table "bar" (
  "id"          integer primary key,
  "name"        varchar,
  "fk_foo"      integer references foo(id)
);

我想知道哪些对于实体最好,在实体类中使用foo对象作为外键引用,或者在实体中使用整数。

使用Netbeans 6.9我生成了以下实体:

@Entity
@Table(name = "bar")
@NamedQueries({
    @NamedQuery(name = "Bar.findAll", query = "SELECT b FROM Bar b"),
    @NamedQuery(name = "Bar.findById", query = "SELECT b FROM Bar b WHERE b.id = :id"),
    @NamedQuery(name = "Bar.findByName", query = "SELECT b FROM Bar b WHERE b.name = :name")})
public class Bar implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Column(name = "name")
    private String name;
    @JoinColumn(name = "fk_foo", referencedColumnName = "id")
    @ManyToOne
    private Foo foo;

    public Bar() {
    }


@Entity
@Table(name = "foo")
@NamedQueries({
    @NamedQuery(name = "Foo.findAll", query = "SELECT f FROM Foo f"),
    @NamedQuery(name = "Foo.findById", query = "SELECT f FROM Foo f WHERE f.id = :id"),
    @NamedQuery(name = "Foo.findByName", query = "SELECT f FROM Foo f WHERE f.name = :name")})
public class Foo implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Column(name = "name")
    private String name;
    @OneToMany(mappedBy = "foo")
    private Collection<Bar> barCollection;

    public Foo() {
    }

现在,当我必须创建一个新的Bar对象时,我还必须创建一个新的Foo对象。所以我创建了以下栏。请记住,我从实体中删除了setter和所有默认构造函数。

Bar bar1 = new Bar(1); bar1.setName( “wheatly”); bar1.setFoo(new Foo(1));

与为Foo使用字段类型的整数相反:

Bar bar2 = new Bar(1); bar2.setName( “GLaDOS的”); bar2.setFoo(1);

我更喜欢自己的第二种方法。是否有理由选择第一条路线更好?我遇到的一个问题是解组XML我已经组合了实体和JAXB对象,在他们的例子中,Foo对象被设置为一个完全为空的Foo对象而不是id为1的Foo对象。

您怎么看?

2 个答案:

答案 0 :(得分:2)

嗯,它被称为对象关系映射:)。如果你没有在更简单的JDBC包装器中找到JPA的附加功能的价值,那么有更多轻量级的替代品可以将数据库列值填充到对象中。

映射对象的第一件事就是允许您在JPQL中自然地编写联接。您不能在JPQL中进行任意连接,必须将它们定义为对象映射。

例如,如果您在条形图上的所有内容都是ID的数字值,并且您希望找到具有特定foo的数字,那么您最终会使用

select b from Bar b, Foo f where bar.fooId = f.id and f.name = :fooName;

如果你用正常的对象引用方式映射它,你可以编写

select b from Bar b where b.foo.name = :fooName;

根据您正在使用的数据库以及是否/如何重写查询,第一个查询中的笛卡尔积可能是坏消息。

其次,如果不映射对象,则不能使用传递持久性。您将重新使用EntityManager显式地导致每个单独的插入和更新,就像它只是一个JDBC包装器一样。通过传递持久性(CASCADE设置)将所有显式持久化/合并插入/更新抽象到ORM层是JPA提供的主要内容之一,而不是简单的JDBC包装器。

例如,如果您在CascadeType.PERSIST中标记了@OneToMany栏的列表,那么您可以通过这样做来制作新栏:

beginTransaction();
Foo foo = em.find(Foo.class, 1);
Bar newBar = new Bar();
//set up your Bar
foo.getBarCollection().add(newBar);
commitTransaction();

完成!

答案 1 :(得分:0)

似乎您在询问是否使用Integer Object或int数据类型。如果是这样,我会推荐int数据类型。当他们意识到将数值放入Integer和Double对象既麻烦又浪费内存空间时,Java想出了它们。对象是指存储您放入其中的所有值的位置,因此允许您放入多个变量。数据类型只存储数据。