我在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中对此进行了更详细的说明。

10-05 23:09