2011-12-20 2 views
7

Несмотря на то, что мой вопрос сформулирован специально для того, как отношения Entity отображаются в структуре Play, которая использует Hibernate, я уверен, что это общий концепция.Попытка понять важность принадлежности стороне отношения «один-много» в ORM

Когда у нас есть отношения «один ко многим», мы всегда просим указать вашу сторону.

Так, например, если бы у нас были отношения «один ко многим» между Person и PhoneNumber, мы бы писали код следующим образом.

@Entity 
class Person { 
    @OneToMany(mappedBy="person") 
    public Set<PhoneNumber> phoneNumbers; 
} 

@Entity 
class PhoneNumber { 
    @ManyToOne 
    public Person person; 
} 

В вышеуказанном коде владеющее лицо является PhoneNumber. Каковы плюсы и минусы любой из сторон, являющихся собственностью?

Я понимаю, что если владельцем является PhoneNUmber, то представленная взаимосвязь представляет собой ManyToOne, которая не будет приводить к таблице соединений, тогда как когда владеющей стороной является Person, обозначенная связь будет OneToMany, и в этом случае таблица отношений будет быть создан.

Является ли это основной причиной для определения стороны владения или существуют другие причины?

Update: Я просто понял, что this thread обеспечивает часть ответа, но я надеюсь, могут быть и другие точки, а также.

ответ

1

С большинством слоев ORM у вас есть концепция ленивой загрузки. Когда вы создаете объект Person, он не будет загружать телефоны, если их не спросят. Время от времени, как вы хотите, чтобы данные поиска могли также определять, как вы его храните.

Как и прежде, если вы хотите воспитывать человека сначала, а затем показывать номера телефонов по требованию, то поддерживать ссылки на телефоны в порядке. Сначала вы запускаете простой запрос для загрузки данных пользователя, а затем просто просматриваете телефонные номера на основе (уже загруженного) person.id (еще один простой запрос)

Принимая во внимание, что если вы показываете человека + телефонные данные за один раз, таблицу соединений, в которой вы можете просто загружать данные на основе таблицы персонализации + персональный телефон, используя идентификатор пользователя в виде ключей в телефонную таблицу, все за один раз. Здесь было бы дорого сделать поиск без таблицы отношений.

Но, откровенно говоря, если вы думаете, SQL вместо ОРМ, то вы бы с таблицей отношений каждый раз: D

+0

Я пытаюсь думать вслух. Предположим, что в обоих случаях мы получаем желаемую выборку. В первом случае, когда PhoneNumber является владельцем объекта, мы будем запускать первый запрос для получения всех объектов Person, а затем запускать индивидуальные запросы для каждого Person, чтобы получить все PhoneNumber для этого Лица. Однако, если бы у нас был Личность как собственная сторона, нам нужно только один запрос с соединением. Прошу прощения, если это глупый вопрос, но нельзя ли присоединиться к человеку, являющемуся FK в PhoneNumber? – Parag

+0

Да, соединение должно быть возможно с личным идентификатором FK в телефонном столе.Здесь я (предполагаю), что нормализованный поиск будет быстрее, но вы должны быть уверены в своем плане объяснения. Еще одна причина (по крайней мере теоретическая) использовать таблицу отношений - это разрешить совместное использование телефонных номеров, таких как номер телефона, используемый двумя людьми в смену. Честно говоря, как работает слой ORM, для таких соображений должно быть несущественным, потому что никто не проектирует схему со слоем ORM в виду – rjha94

+0

см. Мой ответ в этой ветке, а также по причинам «MappedBy» и «владеющей стороны», что происходит если мы не определяем владельца, GOTCHA - http://stackoverflow.com/questions/2749689/what-is-the-owning-side-in-an-orm-mapping/21068644#21068644 –

6

важный момент, чтобы иметь в виду, что владеющее отношение является тот, который на самом деле сохраняться отношение сверху save. С примером:

Person person = new Person(); 
    PhoneNumber pn = new PhoneNumber(); 
    pn.phone = "12345678"; 
    person.phoneNumbers.add(pn); 
    session.save(person); 

Отношения не спасти Infact, если вы загрузите объект из базы данных вы не увидите никаких цифр. Чтобы на самом деле добавить отношение, необходимо установить человека на стороне владельца (PhoneNumber), а затем сохранить.

// the relation is not saved 
    Person loadedPerson = (Person)session.load(Person.class, person.id); 
    System.out.println(loadedPerson.phoneNumbers.size()); // prints 0! 

    pn.person = person; 
    session.save(pn); 

    loadedPerson = (Person)session.load(Person.class, person.id); 
    System.out.println(loadedPerson.phoneNumbers.size()); // prints 1