How to persist @ManyToMany relation - duplicate entry or detached entity

后端 未结 5 1910
一整个雨季
一整个雨季 2020-12-01 06:36

I want to persist my entity with ManyToMany relation. But i have some problem during persisting process.

My entities :

@Entity
@Table(name = \"USER\"         


        
5条回答
  •  春和景丽
    2020-12-01 07:13

    I have the same issue, but couldn't get through it yet. My RelationShip is Hotel to DeliveryPartners. Following are the classes:

    @Entity Class 
    
    package com.hotelapp.models;
    
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    import javax.persistence.*;
    import java.util.Set;
    
    @Entity
    @Getter
    @Setter
    @NoArgsConstructor
    public class Hotel {
    
        @Id
        @GeneratedValue(generator = "hotel_id", strategy = GenerationType.AUTO)
        @SequenceGenerator(name = "hotel_id", sequenceName = "hotel_id")
        private Integer hotelId;
        private String hotelName;
        @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
        @JoinColumn(name = "address_id")
        private Address address;
        @OneToMany(cascade =  CascadeType.ALL, fetch = FetchType.EAGER)
        @JoinColumn(name = "hotel_id")
        private Set menuList;
        @ManyToMany(cascade = {CascadeType.MERGE} ,fetch = FetchType.EAGER)
        @JoinTable(name ="hotel_delivery", joinColumns = @JoinColumn(name ="hotel_id"), inverseJoinColumns = @JoinColumn(name="delivery_id"))
        private Set delivery;
    
        public Hotel(String hotelName, Address address, Set menu, Set delivery) {
            this.hotelName = hotelName;
            this.address = address;
            this.menuList = menu;
            this.delivery = delivery;
        }
    
        @Override
        public String toString() {
            return "Hotel{" +
                    "hotelName='" + hotelName + '\'' +
                    ", address=" + address +
                    ", menu=" + menuList +
                    ", delivery=" + delivery +
                    '}';
        }
    }
    
    @Delivery Class
    
    package com.hotelapp.models;
    
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    import javax.persistence.*;
    import java.util.HashSet;
    import java.util.Set;
    
    @Entity
    @Getter
    @Setter
    @NoArgsConstructor
    public class Delivery {
    
        @Id
        @GeneratedValue(generator = "del_id", strategy = GenerationType.AUTO)
        @SequenceGenerator(name = "del_id", sequenceName = "delivery_id")
        private Integer deliveryId;
        private String partnersName;
        private Double charges;
        @ManyToMany(mappedBy = "delivery", cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
        @JsonIgnore
        private Set hotelList = new HashSet<>();
    
        public Delivery(String partnersName, Double charges) {
            this.partnersName = partnersName;
            this.charges = charges;
        }
    
        @Override
        public String toString() {
            return "Delivery{" +
                    "partnersName='" + partnersName + '\'' +
                    ", charges='" + charges + '\'' +
                    '}';
        }
    }
    

    @Controller Class

      @PostMapping("/hotels")
        public ResponseEntity addHotel(@RequestBody Hotel hotel){
            Hotel hotel1 =hotelService.addHotel(hotel);
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("desc", "oneHotelAdded");
            return ResponseEntity.ok().headers(httpHeaders).body(hotel1);
        }
    

    When I use merge cascade type, getting following exception:

    Hibernate: insert into address (city, state, street_name, zip_code, address_id) values (?, ?, ?, ?, ?)
    Hibernate: insert into hotel (address_id, hotel_name, hotel_id) values (?, ?, ?)
    Hibernate: insert into menu (hotel_id, menu_name, price, menu_id) values (?, ?, ?, ?)
    Hibernate: insert into menu (hotel_id, menu_name, price, menu_id) values (?, ?, ?, ?)
    Hibernate: insert into menu (hotel_id, menu_name, price, menu_id) values (?, ?, ?, ?)
    Hibernate: insert into hotel_delivery (hotel_id, delivery_id) values (?, ?)
    2020-07-12 00:13:37.973 INFO 50692 --- [nio-9098-exec-1] o.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
    2020-07-12 00:13:38.026 ERROR 50692 --- [nio-9098-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance - **save the transient instance before flushing: com.hotelapp.models.Delivery; nested exception is java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.hotelapp.models.Delivery] with root cause
    org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.hotelapp.models.Delivery**
    at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:347) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.type.EntityType.getIdentifier(EntityType.java:495) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.type.EntityType.nullSafeSet(EntityType.java:280) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:930) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1352) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:52) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:1.8.0_221]
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    

    I realise from the queries part there is no insert query for delivery table so that delivery can be used in hotel_delivery (MTM Table). Don't know how to proceed now.

提交回复
热议问题