Составной ключ и иерархия

 
 
 
Сообщения:106
Добрый день. Возникла задача для которой никак не могу подобрать устраивающее решение. Для наглядности приведу пример.

Будем организовывать учет штурмовиков в звездолетах. В каждом звездолете летит по 100 тыс. штурмовиков, у каждого на шлеме индивидуальный номер от 1 до 100 000 (нумерация в рамках одного звездолета). Каждый штурмовик имеет непосредственного командира, который тоже имеет командира, .... и так до командующего звездолетом. У каждого штурмовика есть еще какая-то информация, которая для примера не представляет интереса, поэтому мы просто сделаем одно поле info.
Итак:

create table starship(
  id bigint primary key,
  name varchar(100)
)

create table trooper(
  personal_number int not null,
  starship bigint not null refference starship (id),
  info varchar(1000),
  commander int,
  primary key(personal_number, starship),
  foreign key(commander, starship) refference trooper(personal_number, starship)
)


Мы эту информацию хотим всячески CRUD. Для этого делаю классы сущностей. Примерно вот так:

@Entity(name = "starship")
public class Starship (
	@Id
    @Column(name = "id", unique = true)
    private Long id;

    @Column(name = "name")
    private String name;
)

@Entity(name = "trooper")
public class Trooper {

    @EmbeddedId
    private TrooperKey id;

    @Column(name = "info")
    private String info;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumns({
            @JoinColumn(name = "commander", referencedColumnName = "personal_number", insertable = false, updatable = false),
            @JoinColumn(name = "starship", referencedColumnName = "starship", insertable = false, updatable = false)
    })
    @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;
	
}


И есть одна загвоздка со связями. Так как у нас две связи с полем "starship", то нам необходимо указать где "insertable = false, updatable = false". Но мы не можем сделать
@JoinColumns({
            @JoinColumn(name = "commander"),
            @JoinColumn(name = "starship", referencedColumnName = "starship", insertable = false, updatable = false)
    })

потому что нужно делать оба поля "insertable = false, updatable = false", или не делать ни одно.

Но тогда при записи у нас поле commander не пишется (((

Подскажите, пожалуйста, как подобные задачи решаются без добавления искусственного первичного ключа id со счетчиком (если конечно они так решаются). И вообще как правильнее реализовать такой функционал?
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет