В вашем сценарии атрибут mappedBy не должен оказывать никакого влияния.
Я был озадачен именем первичного ключа (оно отличается от "id"), но использование нестандартного имени в качестве идентификатора (каким-то образом, как и ожидалось) не вызывает проблемы, с которой вы сталкиваетесь.
Я экспериментировал с параметром mappedBy в контексте ассоциаций OneToMany и OneToOne и хотел бы поделиться своими выводами. У меня есть похожий сценарий для целей тестирования и для иллюстрации воздействия.
Person.class:
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
@Column(name = "name")
private String name;
@OneToOne
private Address address;
}
Address.class (для OneToOne тестов):
@Entity
public class Address {
@Id
@GeneratedValue
private Long id;
@Column(name = "address")
private String address;
@OneToOne(mappedBy="address")
private Person person;
@OneToMany(cascade = CascadeType.ALL)
private Set<Phone> phone = new HashSet<Phone>();
}
Phone.class (для OneToMany тестов):
@Entity
public class Phone {
@Id
@GeneratedValue
private Long id;
@ManyToOne(optional = false)
private Person person;
@Column(name = "number")
private String number;
}
Перемещая параметр «mappedBy» для ассоциации OneToOne, в любом случае операторы sql, выполняемые hibernate, оставались прежними:
Hibernate:
/* insert domain.Address
*/ insert
into
Address
(id, address)
values
(default, ?)
Hibernate:
/* insert domain.Person
*/ insert
into
Person
(id, address_id, name)
values
(default, ?, ?)
Для OneToMany ассоциаций я обнаружил, что если вы не укажете "mappedBy", hibernate автоматически использует таблицу соединений, тогда как с параметром "mappedBy" ассоциация отображается как отдельный столбец в таблице сущностей.
Если я использую ...
@OneToMany(cascade = CascadeType.ALL)
private Set<Phone> phone = new HashSet<Phone>();
... сохранение лица с одной телефонной записью приводит к выполнению следующих операторов:
Hibernate:
/* insert domain.Phone
*/ insert
into
Phone
(id, number, person_id)
values
(default, ?, ?)
Hibernate:
/* insert collection
row domain.Person.phone */ insert
into
Person_Phone
(Person_id, phone_id)
values
(?, ?)
Принимая во внимание, что ...
@OneToMany(mappedBy="id", cascade = CascadeType.ALL)
private Set<Phone> phone = new HashSet<Phone>();
приводит к несколько иной реляционной модели, которая ближе к тому, что можно было бы ожидать в этом случае:
Hibernate:
/* insert domain.Phone
*/ insert
into
Phone
(id, number, person_id)
values
(default, ?, ?)