Как сохранить данные через JPA без первичного ключа - PullRequest
1 голос
/ 21 июня 2019

У меня есть данные, которые проходят через мое приложение, и обычно их не нужно беспокоить, но для реализации новой функции мне нужно временно их хранить (например, 1 час).Входящие данные могут быть точно такими же, как то, что уже есть, поэтому нет необходимости в первичном ключе.Однако для JPA Entities нужен идентификатор, а мне не нужен / не нужен.Это мешает мне заставить его работать.

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

Это моя сущность, которая хранит данные, которые мне нужны для сохранения.

@Entity
@Table(name = "quoteOrderHistory")
public class QuoteOrderHistory {

    @Column(name = "storeNumber")
    private int storeNumber;

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

    @Column(name = "quoteSaleDate")
    private Date quoteSaleDate;

    @Column(name="orderTotal")
    private BigDecimal orderTotal;

    @Column(name="orderHistoryDate")
    private Timestamp orderHistoryDate;

    // Constructors, Getters and Setters

}

Это мой репозиторий для доступа к данным.

@Repository
public interface QuoteOrderHistoryRepository extends JpaRepository<QuoteOrderHistory, Long> {

    @Query("DELETE FROM QuoteOrderHistory q WHERE q.orderHistoryDate > date")
    void deleteAllExpired(Date date);

    @Query("SELECT q FROM QuoteOrderHistory q WHERE q.storeNumber = ?1 AND q.invoiceNumber = ?2 ORDER BY q.orderHistoryDate DESC")
    List<QuoteOrderHistory> findAllByStoreAndInvoiceDesc(int storeNumber, String invoiceNumber);
}

Я не могу понять, чтобы получить этоРабота.Опять же, первичный ключ не нужен, поскольку предполагается, что он поддерживает повторяющиеся записи.Если есть другой способ обойтись без использования JPA, тогда я полностью за это, но в настоящее время кажется, что легче всего сохранить данные.Если вам нужна дополнительная информация, просто дайте мне знать.Я также мог бы упустить что-то, что можно сделать, чтобы избежать всего этого вместе, но я не настолько знаком с JPA.Так что вся помощь приветствуется.

Ответы [ 2 ]

2 голосов
/ 21 июня 2019

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

https://hashrocket.com/blog/posts/running-out-of-ids

Скажем, бизнес настолько хорош, что мы вставляем в нашу таблицу 10 000 записей в минуту,Итак, сколько времени потребуется, чтобы максимально увеличить нашу последовательность?1750380517 лет

С Насколько большим может быть идентификатор в postgresql

Name        Storage Size    Description                       Range
smallint    2 bytes         small-range integer               -32768 to +32767
integer     4 bytes         usual choice for integer          -2147483648 to +2147483647
bigint      8 bytes         large-range integer               -9223372036854775808 to 9223372036854775807
serial      4 bytes         autoincrementing integer          1 to 2147483647
bigserial   8 bytes         large autoincrementing integer    1 to 9223372036854775807

Если вы отчаянно не хотите использовать столбец идентификаторов по какой-то причине, яневозможно понять, похоже, что вы можете сделать это в JPA, сделав каждый столбец частью описания первичного ключа, но тогда ваши удаления и обновления будут удалять / обновлять любое количество записей.Я не испытал это.Я НЕ БУДУ РЕАЛИЗОВАТЬ ЭТО НА СЕРВЕРЕ ПРОИЗВОДСТВА.

https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#No_Primary_Key

Иногда ваш объект или таблица не имеют первичного ключа.Лучшее решение в этом случае - добавить сгенерированный идентификатор к объекту и таблице.Если у вас нет этой опции, иногда в таблице есть столбец или набор столбцов, которые составляют уникальное значение.Вы можете использовать этот уникальный набор столбцов в качестве идентификатора в JPA.Идентификатор JPA не всегда должен соответствовать ограничению первичного ключа таблицы базы данных, а также не требуется первичный ключ или ограничение уникальности.

Если в вашей таблице действительно нет уникальных столбцов, используйте все столбцы в качествеЯ бы.Обычно, когда это происходит, данные доступны только для чтения, поэтому, даже если таблица допускает дублирование строк с одинаковыми значениями, объекты в любом случае будут одинаковыми, поэтому не имеет значения, что JPA считает, что это один и тот же объект.Проблема с разрешением обновлений и удалений заключается в том, что невозможно однозначно идентифицировать строку объекта, поэтому все соответствующие строки будут обновлены или удалены.

Если у вашего объекта нет идентификатора, но есть таблицаделает, это хорошо.Сделайте объект встраиваемым объектом, встраиваемые объекты не имеют идентификаторов.Вам понадобится объект, который содержит эту Embeddable, чтобы сохранить его и запросить его.

0 голосов
/ 21 июня 2019

Указанный Jazzepi был верным, но меня строго попросили не использовать автоматически сгенерированный номер в качестве идентификатора.Поэтому люди связали это здесь , изображающее с использованием UUID.Это лучший выбор для этой проблемы, поскольку объекты в базе данных рассчитаны на то, чтобы находиться там не более нескольких часов.Поскольку дело обстоит именно так, UUID никогда не будет переполнен, и вероятность повторного UUID внутри таблицы в любой конкретный момент времени практически равна нулю, так как большинство не останется там.

Новый класс сущностей:

@Entity
@Table(name = "quoteOrderHistory")
public class QuoteOrderHistory {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
    @Column(name = "uuid", unique = true)
    private String uuid;

    @Column(name = "storeNumber")
    private int storeNumber;

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

    @Column(name = "quoteSaleDate")
    private Date quoteSaleDate;

    @Column(name="orderTotal")
    private BigDecimal orderTotal;

    @Column(name="orderHistoryDate")
    private Timestamp orderHistoryDate;

    // Constructor, getters, setters

}
...