У меня есть проблема, которую я не могу решить правильно. Я подготовил пример, чтобы проиллюстрировать это.
Давайте вести счет солдат на звездных кораблях. У нас есть несколько солдат в каждом корабле. У каждого солдата есть личный номер, который уникален для космического корабля. И у каждого солдата есть старший офицер, который также является солдатом, и у него также есть старший офицер и так далее. У нас есть другая информация о солдатах, это не имеет значения, поэтому мы просто добавляем поле «информация».
Итак:
create table starship(
id bigint primary key,
name varchar(100)
)
create table trooper(
personal_number int not null,
starship bigint not null reference starship (id),
info varchar(1000),
commander int,
primary key(personal_number, starship),
foreign key(commander, starship) reference trooper(personal_number, starship)
)
У нас есть два стола. «Звездный корабль» с именем и идентификатором звездолета, а также «солдат», где у нас есть личный номер военнослужащего, его номер корабля, информация и личный номер его командира.
Мне нужно сделать CRUD-операции с этими данными, но я не могу построить правильные объекты. Вопрос о записи данных «командира».
Я пытаюсь сделать это таким образом.
Starship:
@Entity(name = "starship")
public class Starship (
@Id
@Column(name = "id", unique = true)
private Long id;
@Column(name = "name")
private String name;
)
Trooper:
@Entity(name = "trooper")
public class Trooper {
@EmbeddedId
private TrooperKey id;
@Column(name = "info")
private String info;
@ManyToOne
@MapsId(value = "type")
@JoinColumns({
@JoinColumn(name = "parent", referencedColumnName = "portal_id"),
@JoinColumn(name = "type", referencedColumnName = "type")
})
@NotFound(action = NotFoundAction.IGNORE)
private Trooper commander;
@OneToMany(mappedBy = "commander", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Trooper> subitems = new HashSet<>();
}
Ключ солдата:
@Embeddable
public class TrooperKey implements Serializable {
@Column(name = "personal_number")
private Long personalNumber;
@ManyToOne()
@JoinColumn(name = "starship")
private Starship starship;
}
Я пытаюсь использовать @MapsId
, потому что в противном случае мне нужно пометить это объединение как insertable = false, updatable = false
. Но он все равно не сохраняет номер командира в поле commander
в базе данных.