Javers с Spring Boot возвращает ENTITY_INSTANCE_WITH_NULL_ID для поля @Transient

Я только начал использовать Javers в своем приложении, но у меня есть объекты, отмеченные @Transient, которые, как я думал, Javers проигнорирует, но нет :(, вместо этого он выдает мне исключение:

JaversException ENTITY_INSTANCE_WITH_NULL_ID: Found Entity instance 'ProductData' with null Id-property 'id'

Вы знаете, есть ли способ игнорировать эти переходные поля?

В Документация говорится, что аннотация @Transient является синонимом @DiffIgnore. Но я не знаю, связано ли это только со сравнением или с ходом аудита.

Вот мой код:

@Entity
public class ProductExternal extends AbstractEntity implements ExternalEntity {

    @Transient
    private ProductData productData;

    @NotNull
    @Column(unique=true)
    private Long externalId;

    public ProductExternal() { }

    //get set
}

--

@Entity
public class ProductData extends AbstractEntity {

private static final long serialVersionUID = 1L;

@Column
@NotNull
private String name;

public ProductData() { }


//get set
}

Родительский класс

@MappedSuperclass
public abstract class AbstractEntity implements Serializable  {

    public AbstractEntity() {}

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected Long id;

    @Version
    @Column(columnDefinition = "bigint default '0'")
    protected Long version;

    //get set

}

person Otávio Augusto Junior    schedule 18.11.2019    source источник


Ответы (1)


Ваш класс и сопоставление (аннотации) кажутся прекрасными. Исключение говорит:

Found Entity instance 'ProductData' with null Id-property 'id'

Итак, вы пытаетесь зафиксировать в Javers объект класса ProductData, который имеет нулевое поле id. Очевидно, что это невозможно. Это обычная проблема с магией @GeneratedValue Hibernate. Ваше поле в первую очередь имеет значение null, а затем оно обновляется позже Hibernate после вызова последовательности БД next val.

Как правило, вы должны вызывать Javers commit() после завершения Hibernate с сохранением вашего объекта. Этого легко добиться, используя один из аспектов автоаудита Джаверса: @JaversAuditable или @JaversSpringDataAuditable. Они применяются в нужной фазе и вызывают Javers commit() для вас. См. https://javers.org/documentation/spring-integration/#auto-audit-aspect.

person Bartek Walacik    schedule 19.11.2019
comment
Но мой объект является переходным объектом, у него не будет идентификатора, даже после фиксации Hibernate, hibernate проигнорирует его. Таким образом, нет способа установить атрибут Id, если мы следуем потоку гибернации. Что я сделал в качестве палиативного решения, так это установил поддельный идентификатор, но было бы здорово, если бы я мог игнорировать все поля @Transient. Если нет, я проверю этот запрос как решенный, мне просто нужен окончательный ответ, возможно это или нет. Кстати, я уже использую @JaversSpringDataAuditable - person Otávio Augusto Junior; 19.11.2019
comment
Вы имеете в виду, можете ли вы игнорировать аннотацию @Transient? - person Bartek Walacik; 19.11.2019
comment
Да, игнорировать поля @Transient от аудита. Джаверс проигнорировал бы их, для меня они не имеют значения. Никому никогда не приходилось игнорировать определенные поля? - person Otávio Augusto Junior; 19.11.2019
comment
@OtávioAugustoJunior, Javers игнорирует поля и геттеры с @Transient ann, это довольно логично - person Bartek Walacik; 20.11.2019
comment
Я ничего не изменил в своем коде выше, и если я не устанавливаю поддельный идентификатор для своего переходного объекта, я получаю эту ошибку with null Id-property 'id'error. И даже установка идентификатора, результат изменений Javers: i.imgur.com/wYf29Gh.png. Это НЕ игнорирует поле. Я буду отлаживать Javers и пытаться понять структуру, может быть, мне нужно сделать что-то еще. спасибо - person Otávio Augusto Junior; 20.11.2019
comment
Я нашел проблему, пока не знаю, как ее исправить :). Но проблема в том, что мой класс ProductExternal имеет абстрактный родительский класс с именем AbstractProduct (это класс между моим AbstractEntity и «ProductExternal»), а все остальные мои сущности ссылаются на AbstractProduct, а не на ProductExternal. Когда движок Javers сопоставляет все классы сущностей, мой ProductExternal игнорируется. В конце концов, когда Javers пытается сгенерировать идентификатор объекта, javers извлекает для фильтра ignoredProperties AbstractProduct (это пусто), а не ProductExternal, у которого есть мое поле @Transient. - person Otávio Augusto Junior; 21.11.2019