Создание сущности JPA - Объекты против "Примитивов" - PullRequest
3 голосов
/ 20 апреля 2011

У меня вопрос к созданию сущности.Скажем, у меня есть следующие таблицы

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.Поэтому я создаю следующую панель.Помните, что я оставил сеттеры и все конструкторы, кроме стандартных, вне сущностей.

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 вместо объекта Foo с идентификатором 1.

* 1018ты думаешь?

Ответы [ 2 ]

2 голосов
/ 20 апреля 2011

Ну, это называется Объект Реляционное отображение :).Если вы не находите ценность в дополнительных функциях JPA по сравнению с более простыми оболочками JDBC, есть гораздо более легкие альтернативы, которые могут вбивать значения столбцов базы данных в объект.

Первое, что сопоставление ваших объектов делает для вас, этопозволяет писать соединения естественно в JPQL.Вы не можете делать произвольные объединения в JPQL, они должны быть определены как сопоставления объектов.

например, если все, что у вас есть на панели, это числовое значение идентификатора, и вы хотите найти одно с определенным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.Абстрагирование от всех явных вставок / обновлений вставки / слияния в слой ORM с помощью транзитивной персистентности (настройки CASCADE) - это одна из основных вещей, которую 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();

done!

0 голосов
/ 20 апреля 2011

Похоже, вы спрашиваете, использовать ли объект Integer или тип данных int.Если это так, я бы порекомендовал тип данных int.Java придумала их, когда они поняли, что помещение числовых значений в объекты Integer и Double было хлопотами и пустой тратой памяти.Объект относится к местоположению, в котором хранятся все значения, которые вы в него поместили, что позволяет вам вводить несколько переменных.Тип данных просто хранит данные.

...