java - JPA 实体创建 - 对象与 "Primitives"

标签 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("小麦"); bar1.setFoo(new Foo(1));

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

Bar bar2 = new Bar(1); bar2.setName("GlaDOS"); bar2.setFoo(1);

我自己更喜欢第二种方法。有没有理由选择第一条路线更好?我遇到的一个问题是在解码 XML 时,我组合了实体和 JAXB 对象,在它们的情况下,Foo 对象被设置为完全空的 Foo 对象,而不是 ID 为 1 的 Foo 对象。

你怎么看?

最佳答案

好吧,它叫做对象关系映射:)。如果您没有发现 JPA 的附加功能比更简单的 JDBC 包装器更有值(value),还有更多轻量级替代方案可以将数据库列值填充到对象中。

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

例如,如果你在 bar 上只有 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 包装器提供的主要功能之一。

例如,如果您在 @OneToMany 中用 CascadeType.PERSIST 标记您的柱状图列表,那么您可以通过这样做来创建新的柱状图:

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

完成!

关于java - JPA 实体创建 - 对象与 "Primitives",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5734092/

相关文章:

JAVA处理文件出现java.lang.OutOfMemoryError : GC overhead limit exceeded error

java - "if then else "使用规则引擎

java - NetBeans 集成开发环境 : Is there a way to make files read-only or lock the contents?

java - netbeans 中的单选按钮

c# - 选择最小和最大 LINQ

entity - 领域驱动设计 : How to deal with User Entities in different bounded context?

java - 使用java读取war文件中的Manifest.mf

java - 如何有效地从另一个字符串中删除一个字符串的所有实例?

java - "JSR-303 Provider is on the classpath"含义

java - @SqlResultSetMapping 列 : entities with sub-entities