Каков правильный подход для использования перечислений в базе данных с JPA? [закрыто]JAVA

Программисты JAVA общаются здесь
Anonymous
Каков правильный подход для использования перечислений в базе данных с JPA? [закрыто]

Сообщение Anonymous »

Я работаю над приложением Spring Boot + JPA, и я смущен наилучшей практикой для постоянных перечислений в базе данных.

Код: Выделить всё

public enum SellerStatus {
PENDING_REVIEW,
APPROVED,
REJECTED;
}
< /code>

[b] подход 1: < /strong> с использованием @enumerated (enumtype.string) < /code> < /p>
@Entity
public class Seller {

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

@Column(name = "status")
@Enumerated(EnumType.STRING)
private SellerStatus status;

// getters/setters
}
Это хранит перечисление как столбец varchar в DB. Это просто и работает хорошо, но у него есть проблемы: < /p>
  • накладные расходы на хранение (хранение длинных строк вместо небольших идентификаторов). < /P>
    < /li>
    , если я переименуйте константу enum

    Код: Выделить всё

    APPROVED
    → Принято , отклонил → Deleted ) Когда в таблице есть миллионы строк, обновление DB будет болезненным.
подход 2 [/b]: Использование таблицы просмотра для значений enum
iss for Creatire> i также. SellerStatus Таблица в DB:
Таблица: Seller_status

Код: Выделить всё

id   |   name
--------------------
1    | PENDING_REVIEW
2    | APPROVED
3    | REJECTED
, а затем ссылайтесь на его в таблице Продавца как иностранная ключ:

Код: Выделить всё

seller
---------
id | name | status_id
< /code>
Теперь в Java я могу отобразить так: < /p>
@Entity
public class Seller {

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

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "status_id")
private SellerStatusEntity status;
}
Но здесь, SellerStatusentity становится объектом, а не перечислением. Это чувствует себя неправильно, так как эти значения фиксируются и редко меняются. Also, this adds an extra join query.
Approach 3: Enum with IDs and @Converter
Another idea is to keep the enum in Java but assign IDs that match the DB table:

Код: Выделить всё

@Getter
@AllArgsConstructor
public enum SellerStatus {
PENDING_REVIEW(1),
APPROVED(2),
REJECTED(3);

private final int id;
}

Затем используйте пользовательский jpa @converter для карты между Enum и Integer в db:

Код: Выделить всё

@Converter(autoApply = true)
public class SellerStatusConverter implements AttributeConverter {

@Override
public Integer convertToDatabaseColumn(SellerStatus status) {
return status != null ? status.getId() : null;
}

@Override
public SellerStatus convertToEntityAttribute(Integer dbData) {
return Arrays.stream(SellerStatus.values())
.filter(s -> s.getId() == dbData)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Unknown status id: " + dbData));
}
}

< /code>
Таким образом: < /p>
[list]
[*]  db остается нормализованным (INTEGER COLMN с иностранным ключом к таблице поиска). < /p>
< /li>
  код Java все еще использует enum. Постоянно, мне также нужно обновить таблицу DB вручную. < /p>
< /li>
< /ul>

 Мой вопрос: < /strong> < /p>

и принимаю проблемы с переименом/обновлением?

[*]  или поддерживает таблицу поиска + @converter 
правильный подход, даже если он добавляет какую -то управление дБ? перечисление в JPA, которое избегает как дополнительных соединений, так и болезненных переименования?

[/list]

Подробнее здесь: https://stackoverflow.com/questions/797 ... e-with-jpa

Вернуться в «JAVA»