Как определить составные первичные ключи? - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть таблица базы данных. DDL для таблицы:

CREATE TABLE `acsblts` (
  `usrnm` varchar(64) NOT NULL,
  `rl` varchar(64) NOT NULL,
  UNIQUE KEY `acsblts_idx_1` (`usrnm`,`rl`),
  CONSTRAINT `acsblts_ibfk_1` FOREIGN KEY (`usrnm`) REFERENCES `lgn_crdntls` (`usrnm`)
)

Теперь я хочу создать Java класс для этой таблицы. Я сделал следующее:

@Entity
@Table(name = "acsblts", uniqueConstraints = { @UniqueConstraint(columnNames = { "rl", "usrnm" }) })
public class Acsblts {

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

    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
    @JoinColumn(name = "usrnm", nullable = false)
    @JsonIgnore
    private LgnCrdntls usrnm;

    // Constructors, Getters, Setters

}

Когда я пытаюсь запустить приложение, отображается ОШИБКА:

Не указан идентификатор для объекта: com.example.mngmntsstm.entity .user.Acsblts

Я понимаю следующее: отсутствие @Id вызывает ОШИБКУ. Как я могу создать составной первичный ключ, используя rl и usrnm.

Является ли хорошей идеей использовать следующий id в качестве primary_key вместо композитный_применный_ключ?

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

Ответы [ 2 ]

1 голос
/ 25 февраля 2020
  1. Я думаю, что самым простым способом в вашем случае будет использование составных идентификаторов с ассоциациями .
@Entity
@Table(name = "acsblts")
public class Acsblts implements Serializable
{
   @Id
   @Column(name = "rl")
   private String rl;

   @Id
   @ManyToOne
   @JoinColumn(name = "usrnm", nullable = false)
   private LgnCrdntls usrnm;

   public Acsblts()
   {}

   public Acsblts(String rl, String usrnm)
   {
      this.rl = rl;
      this.usrnm = new LgnCrdntls(usrnm);
   }

   // getters, setters

   @Override
   public boolean equals(Object obj)
   {
      if (this == obj) return true;
      if (obj == null || getClass() != obj.getClass() ) return false;

      Acsblts that = (Acsblts) obj;
      return Objects.equals(rl, that.rl) &&
             Objects.equals(usrnm, that.usrnm);
   }

   @Override
   public int hashCode()
   {
      return Objects.hash(rl, usrnm);
   }
}

Обратите внимание, что между сущностями нет разделения экземпляр и фактический идентификатор, вы должны передать экземпляр Acsblts в качестве параметра primaryKey методу find.

Acsblts dat = session.find(Acsblts.class, new Acsblts("CRD2", "RL5"));
Вы также можете использовать составные идентификаторы с @EmbeddedId

В этом случае вы должны объявить класс AcsbltsPK следующим образом:

@Embeddable
public class AcsbltsPK implements Serializable
{
   @Column(name = "rl")
   private String rl;

   @ManyToOne
   @JoinColumn(name = "usrnm")
   private LgnCrdntls usrnm;

   @Override
   public boolean equals(Object obj)
   {
      if (this == obj) return true;
      if (obj == null || getClass() != obj.getClass() ) return false;

      AcsbltsPK pk = (AcsbltsPK) obj;
      return Objects.equals(rl, pk.rl) &&
             Objects.equals(usrnm, pk.usrnm);
   }

   @Override
   public int hashCode()
   {
      return Objects.hash(rl, usrnm);
   }
}

А затем используйте его в Acsblts сущности:

@Entity
@Table(name = "acsblts")
public class Acsblts
{
   @EmbeddedId
   private AcsbltsPK pk;

   // ...
}
Вы также можете использовать составные идентификаторы с @IdClass.

Является ли хорошей идеей использовать следующий идентификатор в качестве первичного_ключа вместо составного_применного_ключа?

Вы должны исправить существующую схему для этого. Иногда это неприемлемо.

0 голосов
/ 24 февраля 2020

Использование длинного идентификатора в качестве первичного ключа поможет быстрее искать результаты благодаря индексации, но если вы все еще хотите использовать первичный составной ключ, обратитесь к следующим ссылкам и попытайтесь применить их к вашей проблеме

https://vladmihalcea.com/the-best-way-to-map-a-composite-primary-key-with-jpa-and-hibernate/

https://www.baeldung.com/jpa-composite-primary-keys

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...