Java Spring中使用groovy中的traits组合持久实体时出现的问题

Java Spring中使用groovy中的traits组合持久实体时出现的问题,java,spring,jpa,groovy,traits,Java,Spring,Jpa,Groovy,Traits,我有一个java/groovy组合的Spring应用程序(Groovy2.4.15,SpringDataJPA2.0.9)。我想使用“mixin”方法(在我的例子中,我想使用groovy traits来实现),以便能够从CreatedAt、CreatedBy、Versioned、CretaedBy、SoftDeletable和其他一些traits组成持久实体。它不仅涉及添加带有持久性注释的状态属性,还涉及在一些情况下在trait上实现的相关行为。使用traits/mixin而不是普通继承要方便得

我有一个java/groovy组合的Spring应用程序(Groovy2.4.15,SpringDataJPA2.0.9)。我想使用“mixin”方法(在我的例子中,我想使用groovy traits来实现),以便能够从CreatedAt、CreatedBy、Versioned、CretaedBy、SoftDeletable和其他一些traits组成持久实体。它不仅涉及添加带有持久性注释的状态属性,还涉及在一些情况下在trait上实现的相关行为。使用traits/mixin而不是普通继承要方便得多,因为当您只需要这些属性/行为的某些子集时,有太多的“特殊情况”

这将真正有助于清理大量代码。存在多重继承问题,但当您确切地知道自己在做什么时,该技术就完全可以了

下面是trait实现的一个示例(请注意,所有类都是.groovy,因此在没有字段可见性修饰符的情况下会生成getter和setter):

下面是实现类的示例:

@Entity
@EntityListeners([AuditingEntityListener.class])
@Table(name = "ROOM")
class Room extends SequenceIdEntity<Long> implements
        CreatedAt,
        LastModifiedAt,
        CreatedBy,
        Versioned {

    @Column(name = "NAME", nullable = false)
    String name;
    ...
    ...
}
此尝试或上面不带@AccessType的尝试总是以异常结束,无法在此ManagedType[cz.acrobits.csp.core.jpa.domain.SequenceIdEntity]上找到具有给定名称[createdAt]的属性

可能的解决办法: 也许我在使用getter时做错了什么,这是可以解决的。有什么想法吗?另一种方法是说服Groovy,使其不会更改生成/编译类文件上的字段名。有办法吗?还有其他想法吗

欢迎任何建议,谢谢,
Lukas

在检查了在getter上使用@Access(AccessType.PROPERTY)或@AccessType(Type.PROPERTY)的选项之后,我不得不说,在与groovy traits一起使用时,最好避免使用它。解决方案的稳定性取决于groovy版本。groovy编译或gradle groovy插件中也存在一些bug,当trait从另一个库导入时,这些bug会破坏整个过程。在检查getters上使用@Access(AccessType.PROPERTY)或@AccessType(Type.PROPERTY)的选项后,我不得不说,当它与groovy traits一起使用时,最好避免它。解决方案的稳定性取决于groovy版本。groovy编译或GradleGroovy插件中也存在一些bug,当trait从另一个库导入时,这些bug会破坏整个过程。
@Entity
@EntityListeners([AuditingEntityListener.class])
@Table(name = "ROOM")
class Room extends SequenceIdEntity<Long> implements
        CreatedAt,
        LastModifiedAt,
        CreatedBy,
        Versioned {

    @Column(name = "NAME", nullable = false)
    String name;
    ...
    ...
}
@MappedSuperclass
trait CreatedAt implements ICreatedAt {

    private LocalDateTime createdAt;

    @Column(name = "CREATED_AT", nullable = false, updatable = false)
    @CreatedDate
    @AccessType(AccessType.Type.PROPERTY)
    LocalDateTime getCreatedAt() {
        return this.createdAt
    }

    void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt
    }

}