MappedSupperClass中的JPA ManyToOne

时间:2015-03-28 13:46:10

标签: hibernate jpa

我正在尝试为我的JPA实体创建一些基本的抽象。我有一个基本抽象类AbstractModel,它有IDVersion。我想有另一个Abstract类,扩展AbstractModel添加一些审计列。然后我有我的实际实体代表表。我在ManyToOne课程中有一个AbstractAuditModel映射,但它似乎不喜欢它。甚至可以在MappedSuperClass

中完成此操作

我的代码如下。

AbstractModel.java

@MappedSuperclass
public abstract class AbstractModel implements Serializable {

    @Transient
    protected static final long serialVersionUID = 1L;

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

    @Version
    protected Long version;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getVersion() {
        return version;
    }

    public void setVersion(Long version) {
        this.version = version;
    }

    @Override
    public abstract int hashCode();

    @Override
    public abstract boolean equals(Object obj);

    @Override
    public abstract String toString();
}

AbstractAuditModel.java

@MappedSuperclass
public abstract class AbstractAuditModel extends AbstractModel {

    @CreatedDate
    @Column(name = "created_at", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    protected Date createdAt;

    @LastModifiedDate
    @Column(name = "last_modified_at", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    protected Date lastModifiedAt;

    @CreatedBy
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "created_by")
    protected User createUser;

    @LastModifiedBy
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "last_modified_by")
    protected User modifyUser;

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Date getLastModifiedAt() {
        return lastModifiedAt;
    }

    public void setLastModifiedAt(Date lastModifiedAt) {
        this.lastModifiedAt = lastModifiedAt;
    }

    public User getCreateUser() {
        return createUser;
    }

    public void setCreateUser(User createUser) {
        this.createUser = createUser;
    }

    public User getModifyUser() {
        return modifyUser;
    }

    public void setModifyUser(User modifyUser) {
        this.modifyUser = modifyUser;
    }

    @Override
    public abstract int hashCode();

    @Override
    public abstract boolean equals(Object obj);

    @Override
    public abstract String toString();
}

我正在使用这样的类。

@Entity
@Table(name = "item_snapshot", schema = "honda_ots")
public class ItemSnapshot extends AbstractAuditModel {

// code

}

相关的堆栈跟踪如下。

Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: com.testapp.model.ItemSnapshot.modifyUser
    at org.hibernate.cfg.annotations.CollectionBinder.getCollectionBinder(CollectionBinder.java:330) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1922) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:963) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:796) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3845) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3799) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1412) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846) ~[hibernate-core-4.3.8.Final.jar:4.3.8.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:852) ~[hibernate-entitymanager-4.3.8.Final.jar:4.3.8.Final]
    ... 66 common frames omitted

2 个答案:

答案 0 :(得分:0)

如果您需要@ManyToMany,则必须将其设为List<User>而不是User。您可能还需要添加@JoinTable来保持关系。否则,请将其设置为多对一,这适合您的姓名last_modified_by

答案 1 :(得分:0)

我认为问题在于:

@LastModifiedBy
@ManyToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "last_modified_by")
protected User modifyUser;

首先你需要Set<User> modifiedBy。此外,当您想要@ManyToMany关系时,我认为您必须指定列,该列将保存关系。

@ManyToMany
@JoinTable(name = "user_model_modifications",
joinColumns = @JoinColumn(name = "last_modified_by",
referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "modified_model_id",
referencedColumnName = "id"))
Set<User> modifiedBy;