Составной первичный ключ из двух внешних ключей

#hibernate #spring-mvc #jpa

#спящий режим #spring-mvc #jpa

Вопрос:

У меня проблема в структуре объекта, я использую Hibernate JPA. Класс состоит из классификации пользователей, где первичным ключом будет пользователь (из класса Usuario), а другим — сезон (из класса Temporada). Ниже приведена структура класса:

 @Entity(name = "CLASSIFICACAO")
@Data
public class Classificacao implements Serializable
{
  @Id
  @GeneratedValue(generator="SharedPrimaryKeyGenerator")
  @GenericGenerator(name="SharedPrimaryKeyGenerator",strategy="foreign",parameters =  @Parameter(name="property", value="usuario"))
  @Column(unique = true, nullable = false)
  private String classificacao;
  @Id
  @GeneratedValue(generator="SharedPrimaryKeyGenerator")
  @GenericGenerator(name="SharedPrimaryKeyGenerator",strategy="foreign",parameters =  @Parameter(name="property", value="temporada"))
  @Column(unique = true, nullable = false)
  private Long codTemporada;
  //another fields  
  @OneToOne
  @PrimaryKeyJoinColumn
  private Usuario usuario;
  @ManyToOne
  @PrimaryKeyJoinColumn
  private Temporada temporada;
}
  

Поле ‘classificacao’ получает имя пользователя из обычного внешнего ключа; Раньше у меня не было поля ‘codTemporada’ в качестве основного, и это работало как шарм. ‘classificacao’ получил пользователя и был основным, а ‘temporada’ только иностранным. Но теперь мне нужно, чтобы поле ‘codTemporada’ также было первичным, создавая составной класс первичного ключа. Но я только что получил сообщение об ошибке: нарушено сопоставление столбцов для: usuario.id из: br.com.xxxxx.model.Классификатор.

Любые предложения о том, что я могу сделать?

Ответ №1:

Если у вас есть несколько идентификаторов в сущности, вы должны использовать EmbeddedId . Здесь оба ваших идентификатора являются ограничениями внешнего ключа, поэтому вам нужно использовать @JoinColumn, чтобы соединить их. Пример кода для classificacao class и classificacaoId class .

Classificacao.java

 @Entity
public class Classificacao implements Serializable {

    @Id
    ClassificacaoId id;

    String name;
    // getter and setter

}
  

ClassificacaoId.java

 @Embeddable
public class ClassificacaoId implements Serializable {

    @OneToOne
    @JoinColumn(name = "userId", referencedColumnName = "userId")
    private Usuario usuarioIo;

    @ManyToOne
    @JoinColumn(name = "tempId", referencedColumnName = "id")
    private Temporada temporada;

    // getter and setter

}
  

Сгенерированный SQL в базе данных h2

 create table classificacao (
    name varchar(255), 
    user_id varchar(255) not null, 
    temp_id bigint not null, 
    primary key (temp_id, user_id)
);
create table temporada (
    id bigint not null, 
    name varchar(255), 
    primary key (id)
);
create table usuario (
    user_id varchar(255) not null, 
    name varchar(255), 
    primary key (user_id)
);
alter table classificacao add constraint FK1najxwr5x189iul4rguqc4wyx 
foreign key (user_id) references usuario;
alter table classificacao add constraint FKlvk517howhduqt5ghb4mgx0ko 
foreign key (temp_id) references temporada;