简体   繁体   English

JPA一对一使用联接表

[英]Jpa one to many using join table

I have a room entity, a rule entity and an amenities entity. 我有一个房间实体,一个规则实体和一个设施实体。 What i want to do is have the rule and the amenities entity filled manually beforehand and when i insert a room, i want depending on what rules and amenities the user chose to map the two in two join tables, room_rules and room_amenities. 我想做的是事先手动填写规则和设施实体,当我插入一个房间时,我要根据用户选择的规则和设施,将两者映射到两个联接表(room_rules和room_amenities)中。

How am i supposed to achieve this? 我应该如何实现这一目标? When i persist a new Room Entity, should it already contain the rules and the amenities? 当我坚持一个新的房间实体时,它应该已经包含规则和便利设施了吗? Is it going to work if the collection of those are not mapped as cascade.persist? 如果这些集合没有被映射为cascade.persist,它将起作用吗?

Or should i 1st persist the room without them and then map them to the room? 还是我应该在没有他们的情况下坚持住房间,然后将它们映射到房间?

What should i do? 我该怎么办?

UPDATE UPDATE

My RoomEntity: 我的RoomEntity:

    public class RoomEntity {

        @Id
        @GeneratedValue(strategy= GenerationType.SEQUENCE)
        @Column(name = "id", nullable =false, unique = true)
        private Integer id;

        @Basic
        @Column(name = "title", nullable = false, length = 45)
        private String title;

        @Basic
        @Column(name = "description", nullable = false, length = 300)
        private String description;

        @Basic
        @Column(name = "square_meters", nullable = false)
        private Integer square_meters;

        @Basic
        @Column(name = "overnight_price", nullable = false)
        private double overnight_price;

        @Basic
        @Column(name = "exta_person_price", nullable = false)
        private double exta_person_price;

        @Basic
        @Column(name = "max_people", nullable = false)
        private Integer max_people;

        @Basic
        @Column(name = "min_overnights", nullable = false)
        private Integer min_overnights;

        @Basic
        @Column(name = "beds", nullable = false)
        private Integer beds;

        @Basic
        @Column(name = "bathrooms", nullable = false)
        private Integer bathrooms;

        @Basic
        @Column(name = "bedrooms", nullable = false)
        private Integer bedrooms;

        @Basic
        @Column(name = "transport", length = 300)
        private String transport;

        @Basic
        @Column(name = "neightborhood", length = 300)
        private String neightborhood;

        @Basic
        @Column(name = "house_rules", length = 200)
        private String house_rules;




        @ManyToOne(cascade = CascadeType.MERGE)
        @JoinColumn(name = "room_host", referencedColumnName = "username", /*nullable = false,*/ insertable = false, updatable = false)
        private HostEntity hostEntity;

        public HostEntity getHostEntity() {
            return hostEntity;
        }

        public void setHostEntity(HostEntity hostEntity) {
            this.hostEntity = hostEntity;
        }

        @OneToOne
        @JoinColumn(name = "room_type_id", referencedColumnName = "id", /*nullable = false,*/ insertable = false, updatable = false)
        private TypeEntity typeEntity;

        public TypeEntity getTypeEntity() {
            return typeEntity;
        }

        public void setTypeEntity(TypeEntity typeEntity) {
            this.typeEntity = typeEntity;
        }

        @OneToOne(cascade={CascadeType.ALL})
        @JoinColumn(name = "room_location", referencedColumnName = "id"/*, nullable = false, insertable = false, updatable = false*/)
        private LocationEntity locationEntity;

        public LocationEntity getLocationEntity() {
            return locationEntity;
        }

        public void setLocationEntity(LocationEntity locationEntity) {
            this.locationEntity = locationEntity;
        }


        @OneToMany(cascade = {CascadeType.ALL})
        @JoinTable(
                /*name = "room_pictures",*/
                joinColumns = {@JoinColumn(name = "room_id", referencedColumnName = "id")},
                inverseJoinColumns = {@JoinColumn (name ="picture_id", referencedColumnName = "id", unique = true)}
        )
        private Collection<PictureEntity> pictureEntities = new ArrayList<>();

        public Collection<PictureEntity> getPictureEntities() {
            return pictureEntities;
        }

        public void setPictureEntities(Collection<PictureEntity> pictureEntities) {
            this.pictureEntities = pictureEntities;
        }

        @OneToMany
        @JoinTable(
                /*name = "room_amenities",*/
                joinColumns = {@JoinColumn(name = "room_id", referencedColumnName = "id")},
                inverseJoinColumns = {@JoinColumn (name ="amenity_id", referencedColumnName = "id")}
        )
        private Collection<AmenitiesEntity> amenitiesEntities = new ArrayList<>();

        public Collection<AmenitiesEntity> getAmenitiesEntities() {
            return amenitiesEntities;
        }

        public void setAmenitiesEntities(Collection<AmenitiesEntity> amenitiesEntities) {
            this.amenitiesEntities = amenitiesEntities;
        }

         @OneToMany
         @JoinTable(
                /*name = "room_amenities",*/
                 joinColumns = {@JoinColumn(name = "room_id", referencedColumnName = "id")},
                 inverseJoinColumns = {@JoinColumn (name ="rule_id", referencedColumnName = "id")}
         )
         private Collection<RuleEntity> ruleEntities = new ArrayList<>();

        public Collection<RuleEntity> getRuleEntities() {
            return ruleEntities;
        }

        public void setRuleEntities(Collection<RuleEntity> ruleEntities) {
            this.ruleEntities = ruleEntities;
        }

 public Collection<Picture> toPicturesModel(){
        Collection<Picture> pictures = new ArrayList<>();
        for(PictureEntity o : this.pictureEntities){
            pictures.add(o.toModel());
        }
        return pictures;
    }

    public Collection<Amenities> toAmenitiesModel(){
        Collection<Amenities> amenities = new ArrayList<>();
        for(AmenitiesEntity o : this.amenitiesEntities){
            amenities.add(o.toModel());
        }
        return amenities;
    }

    public Collection<Rule> toRulesModel(){
        Collection<Rule> rules = new ArrayList<>();
        for(RuleEntity o : this.ruleEntities){
            rules.add(o.toModel());
        }
        return rules;
    }


    public Room toModel(Integer depth){
        System.out.println("RoomEntity:::toModel()");
            return new Room(
                this.hostEntity == null? null : this.hostEntity.toModel(depth),
                this.getTypeEntity() == null? null : this.typeEntity.toModel(),
                this.getLocationEntity()== null? null : this.locationEntity.toModel(),
                this.getPictureEntities() == null ? null : this.toPicturesModel(),
                this.getAmenitiesEntities() == null? null : this.toAmenitiesModel(),
                this.getRuleEntities() == null? null : this.toRulesModel(),
                this.title,  this.description,  this.square_meters,
                this.overnight_price,  this.exta_person_price,
                this.max_people,  this.min_overnights,  this.beds,  this.bathrooms,
                this.bedrooms, this.transport,  this.neightborhood, this.house_rules);
    }
}

My HostEntity inherits from RenterEntity the primary key username: 我的HostEntity从RenterEntity继承了主键用户名:

public class HostEntity extends RenterEntity {
@Basic
@Column(name = "about", length = 200)
private String about;

@Basic
@Column(name = "confirmed", nullable = false)
private boolean confirmed;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "hostEntity")
private Collection<RoomEntity> roomEntities;

public Collection<RoomEntity> getRoomEntities() {
    return roomEntities;
}

public void setRoomEntities(Collection<RoomEntity> roomEntities) {
    this.roomEntities = roomEntities;

}

My LocationEntity: 我的LocationEntity:

public class LocationEntity{

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
@Column(name = "id", nullable =false, unique = true)
private Integer id;

@Basic
@Column(name = "latitude", nullable = false, precision = 0)
private double latitude;

@Basic
@Column(name = "longitude", nullable = false, precision = 0)
private double longitude;

@Basic
@Column(name = "street_number", length = STREET_MAX)
private String street_number;

@Basic
@Column(name= "route", length =  ROUTE_MAX)
private String route;

@Basic
@Column(name = "locality", length = LOCALITY_MAX)
private String locality;

@Basic
@Column(name = "postal_code", length = POSTAL_CODE_MAX)
private String postal_code;

@Basic
@Column(name = "country", length = COUNTRY_MAX)
private String country;

@Basic
@Column(name = "administrative_area_level_5", length = ADMINISTRATIVE_AREA_LEVEL_MAX)
private String administrative_area_level_5;

@Basic
@Column(name = "administrative_area_level_4", length = ADMINISTRATIVE_AREA_LEVEL_MAX)
private String administrative_area_level_4;

@Basic
@Column(name = "administrative_area_level_3", length = ADMINISTRATIVE_AREA_LEVEL_MAX)
private String administrative_area_level_3;

@Basic
@Column(name = "administrative_area_level_2", length = ADMINISTRATIVE_AREA_LEVEL_MAX)
private String administrative_area_level_2;

@Basic
@Column(name = "administrative_area_level_1", length = ADMINISTRATIVE_AREA_LEVEL_MAX)
private String administrative_area_level_1;

@Basic
@Column(name = "formatted_address", length = FORMATTED_ADRESS_MAX, nullable = false, unique = true)
private String formatted_address;

}

My TypeEntity: 我的TypeEntity:

public class TypeEntity {

@Id
@Column(name = "id", nullable = false, unique = true)
private Integer id;

@Basic
@Column(name = "type_name", nullable = false, length = 45)
private String type;

@OneToOne(mappedBy = "typeEntity")
private RoomEntity roomEntity;

}

My RuleEntity: 我的RuleEntity:

public class RuleEntity {

    @Id
    @Column(name = "id", nullable =false, unique = true)
    //@GeneratedValue(strategy= GenerationType.SEQUENCE)
    private Integer id;

    @Basic
    @Column(name = "rule", nullable =false , unique = true, length = 50)
    private String rule;
}

My PictureEntity: 我的PictureEntity:

public class PictureEntity {

@Id
@Column(name = "id", nullable =false, unique = true)
@GeneratedValue(strategy= GenerationType.SEQUENCE)
private Integer picture_id;

@Basic
@Column(name = "thumbnail_url", nullable =false, length = 100)
private String thumbnail_url;

@Basic
@Column(name = "medium_url", nullable =false, length = 100)
private String medium_url;

@Basic
@Column(name = "picture_url", nullable =false, length = 100)
private String picture_url;

@Basic
@Column(name = "xl_picture_url", nullable =false, length = 100)
private String xl_picture_url;
}

My AmenitiesEntity: 我的便利设施

public class AmenitiesEntity {

@Id
@Column(name = "id", nullable =false, unique = true)
//@GeneratedValue(strategy= GenerationType.SEQUENCE)
private Integer id;

@Basic
@Column(name = "name", nullable = false, unique = true, length = 50)
private String amenity;
}

My code that creates a room is this: 我创建房间的代码是这样的:

public Room addRoom(RoomInput room) {
        dao.setParam("username", room.getOwner());
        List<HostEntity> owner = dao.getTuples("users.findByUsername");
        RoomEntity newRoom = new RoomEntity(room.getTitle(), room.getDescription(), room.getSquare_meters(), room.getOvernight_price(),
                room.getExta_person_price(), room.getMax_people(), room.getMin_overnights(), room.getBeds(), room.getBathrooms(),
                room.getBedrooms(), room.getTransport(), room.getNeightborhood(), room.getHouse_rules());
newRoom.setLocationEntity(room.getLocation().toEntity());
    for(Picture o :room.getPictures()){
        newRoom.getPictureEntities().add(o.toEntity());
    }
    RoomEntity entity = dao.insertTuple(newRoom);
    entity.setHostEntity(owner.get(0));
    for(Amenities o : room.getAmenities()){
        entity.getAmenitiesEntities().add(o.toEntity());
    }
    for(Rule o : room.getRules()){
        entity.getRuleEntities().add(o.toEntity());
    }
    entity.setTypeEntity(room.getType().toEntity());
    entity = dao.updateTuple(entity);
    System.out.println(entity.toString());
    return (entity == null) ? null : entity.toModel(0);
}

What happens now is that, even though my 3 join tables, room_pictures, room_rules, room_amenities get updated correctly, the room i put in the database has the foreign key of the host(username) and the type(id) null. 现在发生的是,即使我的3个联接表,room_pictures,room_rules,room_amenities正确更新,我放入数据库中的房间也具有主机(用户名)的外键和type(id)为null的外键。

Is there a better way in doing all this? 有没有更好的方法来完成所有这些工作? Right now i 1st persist the new room, and cascade persist the pictures and the location and then i merge the room with the new values of host, amenities and rules updated. 现在,我首先保留新房间,并级联保留图片和位置,然后将房间与主机,便利设施和规则的新值合并。

UPDATE I fixed the problem. 更新我解决了这个问题。 Now i do one insert for the entities i want to persist with the room, aka location and pictures and one merge to connect the detatched entities amenities/rules in the join tables and host/type foreign keys in the room table. 现在,我为要保留在房间中的实体(即位置和图片)做一个插入操作,然后合并一个连接,以连接联接表中已分离的实体的便利设施/规则以及房间表中的主机/类型外键。 The problem with host and type was that i had in the @JoinColumn updateable and instertable to be false which was wrong. 主机和类型的问题是,我在@JoinColumn中具有可更新和不可识别的错误,这是错误的。 After i deleted those statements, it worked! 我删除这些语句后,它起作用了! My code in the end to persist/merge the detatched and new entities is this: 最后,我要保留/合并已分离和新实体的代码是这样的:

 public Room addRoom(RoomInput room) {
        dao.setParam("username", room.getOwner());
        HostEntity host = null;
        List<HostEntity> owner = dao.getTuples("users.findByUsername");
        RoomEntity newRoom = new RoomEntity(room.getTitle(), room.getDescription(), room.getSquare_meters(), room.getOvernight_price(),
                room.getExta_person_price(), room.getMax_people(), room.getMin_overnights(), room.getBeds(), room.getBathrooms(),
                room.getBedrooms(), room.getTransport(), room.getNeightborhood(), room.getHouse_rules());
        System.out.println(owner.get(0).toString());
        newRoom.setLocationEntity(room.getLocation().toEntity());
        for(Picture o :room.getPictures()){
            newRoom.getPictureEntities().add(o.toEntity());
        }
        RoomEntity entity = dao.insertTuple(newRoom);

        for(Amenities o : room.getAmenities()){
            entity.getAmenitiesEntities().add(o.toEntity());
        }
        for(Rule o : room.getRules()){
            entity.getRuleEntities().add(o.toEntity());
        }
        entity.setHostEntity(owner.get(0));
        entity.setTypeEntity(room.getType().toEntity());
        dao.updateTuple(entity);
        System.out.println(entity.toString());
        return (entity == null) ? null : entity.toModel(0);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM