Я чувствую, что на это отвечают 100 раз.но по какой-то причине я попробовал каждый ответ, и ни один из них не решил мою проблему.
У меня есть простой родитель с простым первичным ключом.У него есть список детей.Внешний ключ является частью составного первичного ключа ребенка.БД - postgresql.
Родительский класс
@Entity
@Table(name = "person")
class Person {
@Id
@GeneratedValue(generator = "person_id_seq")
@Column(name = "person_id")
private Long personId;
@OneToMany(mappedBy="person", cascade = CascadeType.ALL)
private List<PersonIdentifier> personIdentifiers = new ArrayList<>();
public void addPersonIdentifier(PersonIdentifier pi) {
this.personIdentifiers.add(pi);
pi.setPerson(this);
}
// other columns and getters / setters left out for brevity
}
Дочерний класс с классом ПК
@Entity
@Table(name = "person_identifier")
@IdClass(PersonIdentifierPK.class)
public class PersonIdentifier {
@Id
@Column(name="person_id")
private Long personId;
@Id
@Column(name="person_identifier")
private String personIdentifier;
@Id
@Column(name="person_identifier_type")
private String personIdentifierType;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="person_id", insertable=false, updatable=false)
private Person person;
// other columns and getters / setters left out for brevity
}
public class PersonIdentifierPK {
@Column(name = "person_id")
private Long personId;
@Column(name = "person_identifier")
private String personIdentifier;
@Column(name = "person_identifier_type")
private String personIdentifierType;
// getters/setters left out
@Override
public int hashCode() {
// implementation
}
@Override
public boolean equals(Object obj) {
// implementation
}
}
ИСПОЛЬЗОВАНИЕ:
Patient p = new Patient();
PersonIdentifier pi = new PersonIdentifier();
pi.setPersonIdentifierType("NAME");
pi.setPersonIdentifier("John Doe");
p.addPersonIdentifier(pi);
personRepository.save(p);
TransactionManager
public static <T> T getRepository(Class<T> repositoryInterface, Project project) {
if (entityManager == null) {
DataSource ds = ConnectionPools.getStagingDB();
emFactory = entityManagerFactory(ds, hibernateProperties(project.getStagingDbJdbcUrl(), project.getStagingDbUserName(), project.getStagingDbPassword()));
EntityManagerCreator creator = new EntityManagerCreator();
entityManager = creator.create(emFactory);
}
final JpaTransactionManager xactManager = new JpaTransactionManager(emFactory);
JpaRepositoryFactory factory = new JpaRepositoryFactory(entityManager);
factory.addRepositoryProxyPostProcessor(new RepositoryProxyPostProcessor() {
@Override
public void postProcess(ProxyFactory factory, RepositoryInformation info) {
factory.addAdvice(new TransactionInterceptor(xactManager, new MatchAlwaysTransactionAttributeSource()));
}
});
return factory.getRepository(repositoryInterface);
}
, если я удалю cascade=CascadeType.ALL
, тогда я получу нового человека в моем лицебаза данных с правильно сгенерированным идентификатором, но таблица person_identifier по-прежнему пуста, очевидно.
однако при каскадном преобразовании не удается что-либо зафиксировать из-за того, что столбец personIdentifier person_id пытается установить значение null.
Насколько я понимаю, с помощью сопоставления, столбца соединения и установки родительского элемента на дочернем элементе этот столбец будет автоматически установлен в том виде, в котором он находится на родительском элементе?
вывод Spring sql выглядиткак это (в родительской таблице есть больше столбцов, я просто удалил их по соображениям конфиденциальности) :
select nextval ('person_id_seq')
insert into person (person_id) values (?)
binding parameter [1] as [BIGINT] - [70]
insert into person_identifier (active, create_date, modified_date, person_id, person_identifier, person_identifier_type) values (?, ?, ?, ?, ?, ?)
binding parameter [1] as [BOOLEAN] - [true]
binding parameter [2] as [TIMESTAMP] - [Thu Sep 19 12:34:52 EDT 2019]
binding parameter [3] as [TIMESTAMP] - [null]
binding parameter [4] as [BIGINT] - [null]
binding parameter [5] as [VARCHAR] - [John Doe]
binding parameter [6] as [VARCHAR] - [NAME]
вы можете видеть, где он передал значение null в person_id вставки person_identifier, даже если онпрошло 70 человек в таблицеs оператор вставки.
это, очевидно, приводит к
ERROR: null value in column "person_id" violates not-null constraint
Я пытался рефакторинг кода множеством способов.Используя встроенный идентификатор, удаляя mappedBy и вместо этого используя joincolumn для родителя.и т. д.