Слияние JPA 2 вставляется вместо обновления, когда первичный ключ имеет UUID - PullRequest
0 голосов
/ 15 мая 2019

Для одного из моих объектов я хочу использовать UUID в качестве первичного ключа вместо Long. Сущность расширяет AbstractEntityUUID:

@MappedSuperclass
public abstract class AbstractEntityUUID implements Serializable {

    private static final long serialVersionUID = 40076842287035126L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;

    public UUID getId() {
        return id;
    }

    @Override
    public int hashCode() {
        if (getId() != null) {
            return getId().hashCode();
        }
        return super.hashCode();
    }

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

}

Сам объект:

@Entity
@Table(schema = "schemaName", name = "order")
@DynamicUpdate
public class Order extends AbstractEntityUUID {

    private static final long serialVersionUID = 6358231835578038565L;

    @Column(precision = 10, scale = 2)
    protected BigDecimal itemPrice;

    @Temporal(TIMESTAMP)
    @Basic(fetch = LAZY)
    protected Date purchaseDate;

    // other properties and getters & setters ...

}

Метод постоянства работает отлично:

Order order = new Order();
order.setItemPrice(BigDecimal.ONE);
order = getEM().persist(order);

В таблице базы данных создается новая строка с правильной информацией. Когда позднее происходит слияние, возникает проблема:

order.setPurchaseDate(new Date());
order = getEM().merge(order);

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

Если первичным ключом является Long с GenerationType.IDENTITY, строка обновляется корректно, и работает как положено.

Он запускается на сервере WildFly 16 с компонентом ejb 3. Реализация Hibernate, кажется, 5.3.9. БД - сервер MySQL 5.7.

Хорошо, если Java генерирует значения UUID, и я бы предпочел не изменять это, если только это не требуется для того, чтобы объект работал с UUID в качестве первичного ключа.

1 Ответ

1 голос
/ 15 мая 2019

Вы уверены, что persist работает должным образом, когда MySql генерирует UUID?Идентификатор объекта совпадает с идентификатором, вставленным в базу данных?

...