JPA (hibernate) онтоманское отношение - PullRequest
3 голосов
/ 27 июля 2010

Я не уверен, что мне не хватает, чтобы установить двунаправленные однотомные отношения (механизм гибернации).Уменьшенная версия модели домена:

class Person {
@OneToMany(mappedBy="personFrom", cascade = CascadeType.PERSIST)
    public List<Relationship> relationships;
}

class Relationship {
@ManyToOne
  public Person personFrom;

  @ManyToOne
  public Person personTo;
}

Некоторые наблюдения:
1. При указанном выше сопоставлении таблица соединения не создается.
2. Когда я удаляю mappedBy(@OneToMany (cascade = CascadeType.PERSIST)), таблица соединения создана, и я могу сохранить отношения через Person.Поле personFrom пустое, но я думаю, что это нормально, поскольку связь поддерживается через таблицу соединений.

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

Редактировать: 1

В соответствии с комментарием Дэна, если важно просмотреть полное содержание класса домена, я расширил их ниже.

class Relationship extends Model{

  @ManyToOne
  public RelationshipType relationshipType;

  @ManyToOne
  public Person personFrom;

  @ManyToOne
  public Person personTo;

  @ManyToOne
  public Person createdBy;

  @ManyToOne
  public Role roleFrom;

  @ManyToOne
  public Role roleTo;

    @Override
    public String toString() {
        return relationshipType.toString();
    }
}

class Person extends Model {

    public Date dateCreated;

    @Lob
    public String description;

    @OneToMany(cascade = CascadeType.ALL)
    public List<Role> roles;

    @OneToMany(mappedBy="personFrom", cascade = CascadeType.PERSIST)
    public List<Relationship> relationships;
}

Роль также связана с Person, но я думаю, что сохранение personFrom, personTo помогает оптимизировать мои запросы.

Role extends Model {

    @ManyToOne
    public RoleType roleType;

    @ManyToOne
    public Person createdBy; 
}

Ответы [ 2 ]

2 голосов
/ 28 июля 2010

с указанным выше отображением таблица соединения не создается.

Таблица соединения не требуется для OneToMany, вы получите столбец внешнего ключа на стороне Много,И вот что я получаю при использовании вашего кода:

create table Person (
    id bigint not null,
    primary key (id)
)

create table Relationship (
    id bigint not null,
    personFrom_id bigint,
    personTo_id bigint,
    primary key (id)
)

alter table Relationship 
    add constraint FK499B69164A731563 
    foreign key (personTo_id) 
    references Person

alter table Relationship 
    add constraint FK499B691698EA8314 
    foreign key (personFrom_id) 
    references Person

Что является ожидаемым результатом (по крайней мере для меня).Возможно, что вы на самом деле хотите, это ManyToMany.

Когда я удаляю mappedBy (@OneToMany (cascade = CascadeType.PERSIST)), создается таблица соединения, и я могу сохранять отношения через Person.Поле personFrom пустое, но я думаю, что это нормально, поскольку связь поддерживается через таблицу соединений.

Я написал небольшой модульный тест, используя предоставленный код (с API Hibernate, но это ничего не меняет), и я не понимаю, в чем проблема (сеанс создается до метода тестаи метод выполняется внутри транзакции):

Person p1 = new Person();
Person p2 = new Person();
Relationship r = new Relationship();

// create the personFrom bi-directional association
r.setPersonFrom(p1);
List<Relationship> relationships = new ArrayList<Relationship>();
relationships.add(r);
p1.setRelationships(relationships); // these four lines should be moved to some 
                                    // link management method (see update below).

// create the personTo uni-directional association
r.setPersonTo(p2);

session.persist(p2);
session.persist(p1);

assertNotNull(p2.getId());
assertNotNull(p1.getId());
assertNotNull(r.getId());

Приведенный выше код приводит к двум вставкам в таблицу Person и одной вставке в таблицу отношений (оценивая 3 столбца).

AsЯ сказал, я не понимаю проблемы.Возможно, вам следует объяснить ожидаемый результат (как для реляционной модели, так и для запросов).

Обновление: Для полной ясности при работе с двунаправленными ассоциациями необходимо установитьОбе стороны ссылки и общий шаблон - использовать методы управления защитной связью, чтобы правильно установить обе стороны ассоциации.Примерно так:

public void addToRelationships(Relationship relationship) {
    if (this.relationships == null) {
       this.relationships = new ArrayList<Relationship>();
    }
    this.relationships.add(relationship);
    relationship.setPersonFrom(this);
}

Это подробно описано в разделе 1.2.6.Рабочие двунаправленные ссылки документации Hibernate.

0 голосов
/ 28 июля 2010

Вы указали имя столбца внешнего ключа в качестве имени столбца соединения?Предполагая, что столбец внешнего ключа называется PERSON_ID, код должен выглядеть примерно так:

class Relationship {
    @ManyToOne
    @JoinColumn(name="PERSON_ID")
    public Person personFrom;
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...