我遇到了一个问题,我如何创建扩展多个基本抽象类的JPA实体(不创建额外的表)。我知道有一个注释@MappedSuperclass
,但只要我们使用extends
并且多重继承不是Java功能,它就能够只创建一个基类。< / p>
例如,我有两个基础:
@MappedSuperclass
public abstract class Authored {
@ManyToOne
private User user;
}
和
@MappedSuperclass
public abstract class Dated {
private String creationDate;
}
我希望我的某些模型只能扩展Authored
,有些只扩展Dated
,有些只扩展。
虽然它只能写
@Entity
public class MyEntity extends Authored {
...
}
或
@Entity
public class MyEntity extends Dated {
...
}
有些讨论建议在线继承类(例如Authored
和AuthoredAndDated
),但这看起来太脏了,这些基础在逻辑上都不能扩展另一个。
ADDITION
我必须注意,这种风格在Django等其他框架中得到支持(由于python中的多重继承),所以JPA不支持它是很奇怪的。
答案 0 :(得分:1)
很抱歉让您失望,但没有其他解决办法,只能按照您的建议创建AuthoredAndDated
。
我们的实体面临同样的问题,并采用相同的程序。
我们有一个
@MappedSuperclass
public class TimestampedObject {
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at")
private Date createdAt;
@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updated_at")
private Date updatedAt;
}
和
@MappedSuperclass
public class IdObject {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id", updatable = false, columnDefinition = "serial")
private Long id;
}
因此我们为此目的创建了TimestampedIdObject
。
修改强>
如果你找到另一个合适的解决方案,如果你可以在这里发布它会很棒,因为我们有同样的问题......
答案 1 :(得分:0)
您应该使用@Embeddable
/ @Embedded
作为目标,将遗传替换为合成。
首先,请勿使用@MappedSuperClass
,而是使用@Embeddable
替代您要与之共享属性的类:
@Embeddable
public class Authored {...}
@Embeddable
public class Dated {...}
在下一步中,您的实体不应继承Authored
或Dated
,而应获取引用它们的属性:
@Entity
public class MyEntity {
@Embedded
private Authored authored;
@Embedded
private Dated dated;
}
如果你想从这里获得行为,你可以在没有这些新属性的情况下进行一般访问,你需要引入一个暴露必要方法的接口。
对于示例,如果MyEntity
应该能够提供有关上次更新和创建的详细信息,您将引入一个接口Authorable
,它定义了访问相关数据的方法。
public interface Authorable { /* necessary methods */ }
MyEntity
将实现此接口:
@Entity
public class MyEntity implements Authorable {
/* previous content plus implemented mehtods from interface */
}