我在Spring Data JPA中还很陌生,对于实现以下情况的最佳方法存在以下疑问:
所以基本上我有以下两个模型类:
房间(代表住宿的房间):
@Entity
@Table(name = "room")
public class Room implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@ManyToOne
@JoinColumn(name = "id_accomodation_fk", nullable = false)
private Accomodation accomodation;
@ManyToOne
@JoinColumn(name = "id_room_tipology_fk", nullable = false)
private RoomTipology roomTipology;
@Column(name = "room_number")
private String number;
@Column(name = "room_name")
private String name;
@Column(name = "room_description")
@Type(type="text")
private String description;
@Column(name = "max_people")
private Integer maxPeople;
@Column(name = "is_enabled")
private Boolean isEnabled;
public Room() {
}
// GETTER AND SETTER METHODS
}
和RoomTipology,它表示房间的拓扑结构(例如:单人房,双人床房等):
@Entity
@Table(name = "room_tipology")
public class RoomTipology implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "tipology_name")
private String name;
@Column(name = "tipology_description")
private String description;
@Column(name = "time_stamp")
private Date timeStamp;
@OneToMany(mappedBy = "roomTipology")
private List<Room> rooms;
@OneToOne(mappedBy = "roomTipology")
private RoomRate roomRate;
// GETTER AND SETTER METHODS
}
好的,使用Spring Data JPA,我将有2个不同的存储库类(一个用于Room实体类,另一个用于RoomTipology实体类,如下所示:
@Repository
@Transactional(propagation = Propagation.MANDATORY)
public interface RoomDAO extends JpaRepository<Room, Long> {
//@Query("FROM Room WHERE accomodation = :id")
List<Room> findByAccomodation(Accomodation accomodation);
}
@Repository
@Transactional(propagation = Propagation.MANDATORY)
public interface RoomTipologyDAO extends JpaRepository<RoomTipologyDAO , Long> {
// METHOD RELATED TO THE ACCESS TO ROOM TIPOLOGY ENTITIES
}
好的,我有以下架构疑问:
我有2个小的存储库类,可以访问语义相似的内容(房间概念和房间拓朴概念都与房间相关)。
此外,如您在RoomTipology实体类的代码中所看到的,还有以下字段:
@OneToMany(mappedBy = "roomTipology")
private List<Room> rooms;
它由@OneToMany注释映射(因为从特定的房间拓扑开始,我想访问这种拓扑的所有房间:所有单人床房间或所有双人床房间,依此类推...)。
因此,按照这种体系结构样式,我将拥有将与房间拓扑相关的List返回到RoomTipologyDAO存储库类而不是RoomTipology存储库类的方法。它工作正常,但在语义上很糟糕,因为我将拥有RoomTipologyDAO不返回与RoomTipology实例相关的内容,而是返回Room对象的列表。
不讨厌吗?
那么在这种情况下创建使用Spring Data JPA的架构的最佳方法是什么?
我不能做类似的事情:
public interface RoomDAO extends JpaRepository<Room, Long> extends JpaRepository<RoomTipology, Long> {
........................................................
........................................................
........................................................
}
因为Java不支持多种遗传,但是我认为最好的选择应该是获得类似的东西。
也许我可以创建像RoomMetaDAO类这样的东西,并将RoomDAO和RoomTipologyDAO作为字段?能行吗
您认为哪种情况最适合我的情况?
最佳答案
您对此表示怀疑是绝对正确的。
错误是假定每个实体应该有一个存储库。相反,您应该研究域驱动设计中聚合根的概念。
聚合根是用于操纵一堆只能通过聚合根访问和修改的实体的实体。
您希望每个这样的聚合根有一个存储库,在您的情况下就是Room。
Spring Data项目负责人Oliver Gierke在this article中对此进行了更详细的说明。