Есть ли какой-либо способ аудита с помощью hibernate-envers сущности, имеющей @Embedded в своем EmbeddedId - PullRequest
0 голосов
/ 05 апреля 2019

У меня есть объект BlocRecord, имеющий составной код BlocRecordId, а в его составном коде есть @Embedded (код отношения ManyToOne), указывающий на другую запись entiy, и я хочу провести аудит объекта BlocRecord.

Сущность BlocRecord

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "blocRecord")
@Access(value = AccessType.FIELD)
@Audited
public class BlocRecord {

    @EmbeddedId

    private BlocRecordId blocRecordId = new BlocRecordId();

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumns({
            @JoinColumn(name = "record_identifier_", referencedColumnName = "identifier_", unique = false, nullable = false),
            @JoinColumn(name = "record_recordType_", referencedColumnName = "recordType_", unique = false, nullable = false)})
    @MapsId("record")
    private Record record;

...

}

Идентификатор класса BlocRecordID

@Embeddable
public class BlocRecordId implements Serializable {


    @Embedded
    private RecordId record;

    @Column(name = "source_")
    String source ;

    @Column(name = "messageType_")
    String messageType ;

Запись сущности

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "records")
@Access(value = AccessType.FIELD)
@Audited
public class Record {

    @EmbeddedId
    private RecordId recordId = new RecordId();


    @OneToMany(targetEntity = BlocRecord.class, fetch = FetchType.LAZY, mappedBy = "record")
    private Set<BlocRecord> blocRecord = new java.util.HashSet<>();

...
}

idClass сущности Запись

@Embeddable
public class RecordId implements Serializable{

    @Column(name = "identifier_")
    String identifier ;

    @Column(name = "recordType_")
    String recordType ;

}

Сбой Hibernate-envers при попытке сгенерировать метаданные записи поля в встраиваемом BlocRecordId, выдается текущее исключение

org.hibernate.MappingException: Type not supported: org.hibernate.type.ComponentType
    at org.hibernate.envers.configuration.internal.metadata.IdMetadataGenerator.addIdProperties(IdMetadataGenerator.java:121)
    at org.hibernate.envers.configuration.internal.metadata.IdMetadataGenerator.addId(IdMetadataGenerator.java:230)
    at org.hibernate.envers.configuration.internal.metadata.AuditMetadataGenerator.generateFirstPass(AuditMetadataGenerator.java:642)
    at org.hibernate.envers.configuration.internal.EntitiesConfigurator.configure(EntitiesConfigurator.java:95)
    at org.hibernate.envers.boot.internal.EnversServiceImpl.doInitialize(EnversServiceImpl.java:154)
    at org.hibernate.envers.boot.internal.EnversServiceImpl.initialize(EnversServiceImpl.java:118)
    at org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl.produceAdditionalMappings(AdditionalJaxbMappingProducerImpl.java:99)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:288)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:417)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:86)
    at org.hibernate.boot.MetadataSources.buildMetadata(MetadataSources.java:179)

Есть ли у вас идеи, как решить проблему?

Спасибо

1 Ответ

0 голосов
/ 08 апреля 2019

В настоящее время Envers не поддерживает идею вложения встраиваемого объекта в встраиваемый объект, когда мы отображаем столбцы идентификаторов, как показано в вашем примере. Единственные допустимые отображения, которые в настоящее время поддерживает Envers, - это если атрибут встраиваемого объекта имеет тип @ManyToOne или @Basic.

Вы можете обойти эту проблему, но она подразумевает, что вы будете немного более явными и не будете использовать RecordId. Я имею в виду переписать BlocRecordId следующим образом:

@Embeddable
public class BlocRecordId implements Serializable {
  @Column(name = "identifier_")
  String identifier;

  @Column(name = "recordType_")
  String recordType;

  @Column(name = "source_")
  String source;

  @Column(name = "messageType_")
  String messageType;

  @Transient
  private RecordId recordId;

  /** Helper method to assign the values from an existing RecordId */
  public void setRecordId(RecordId recordId) {
    this.identifier = recordId.getIdentifier();
    this.recordType = recordId.getRecordType();
  }

  /** Helper method to get the RecordId, caching it to avoid multiple allocations */
  public RecordId getRecordId() {
    if ( recordId == null ) {
      this.recordId = new RecordId( identifier, recordType );
    }
    return this.recordId;
  }
}

Я согласен, что это далеко не идеально, но это, по крайней мере, работает вокруг текущего ограничения кода. Я добавил и добавил HHH-13361 в качестве открытой проблемы, чтобы поддержать это. Вы можете внести свой вклад, если хотите, или я буду работать над тем, чтобы это поддерживалось для Envers 6.0.

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