简体   繁体   中英

Delete both parent and child in @OneToMany relationship

I have an entity called itineraryTraveller , and every itineraryTraveller can have many flightEntity . When I try to delete an itineraryTraveller (parent), from the database, I get this error message:

a foreign key constraint fails (`pquino01db`.`ITINERARYTRAVELLER_FLIGHTENTITY`, CONSTRAINT `FK_ITINERARYTRAVELLER_FLIGHTENTITY_flights_ID` FOREIGN KEY (`flights_ID`) REFERENCES `FLIGHTENTITY` (`ID`))"

Here is my itineraryTraveller entity:

@Entity
public class itineraryTraveller implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private List<flightEntity> flights;

    @Temporal(javax.persistence.TemporalType.DATE)
    private Date departureDate;

    private String departureLocation;
    private String arrivalLocation;
    private double cost;
    private char status;
    private ArrayList<String> stops;
    private String stopPrint;
    private String userName;
    private int iden;

    // ...
}

And the flightEntity looks like this:

@Entity
public class flightEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Temporal(javax.persistence.TemporalType.DATE)
    private Date departureDate;

    private String airlineCode;
    private String flightNumber;
    private String departureLocation;
    private String arrivalLocation;
    private double businessCost;
    private double economyCost;
    private int numBusinessSeats;
    private int numEconomySeats;

    // ...
}

Can someone see the problem? I think my @OneToMany annotation might be missing something, but I'm not sure what. I want to delete both the parent and child at the same time.

Your relationship between the two entities is unidirectional as there is no mapping from flightEntity back to itineraryTraveller entity as you do not have a @JoinColumn on your flightEntity . There can be one of the following solutions for your problem:

  1. Add a @ManyToOne annotation on the flightEntity as follows:

     @Entity public class flightEntity implements Serializable { // .... @ManyToOne @JoinColumn(name="<name_of_foreignkey_column>") private itineraryTraveller traveller; // ... } 

    And you have to add a mappedBy attribute to your @OneToMany annotation:

     @OneToMany(mappedBy="traveller", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) 

    Thereby making the relationship between the entities bidirectional.

This one can solve the problem if you already have tables in the database with a foreign key relationship.

  1. Use @JoinTable annotation on the @OneToMany annotation:

     @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) @JoinTable(name="<join_table_name>", joinColumns=@JoinColumn("TRAVELLER_ID"), inverseJoinColumns=@JoinColumn("FLIGHT_ID")) private List<flightEntity> flights; 

(The names of the columns are considered to be examples, and can be changed.)

This last mapping is useful if you don't have tables in the database with foreign key column defined, and it will create a new table as an association between the tables; which is normally the case in a many-to-many relationships.

If it is possible use @ManyToOne annotation on the flights entity. This is normal way of mapping a one-to-many relationships.

Lastly, there are conventions in Java that state class names should begin with a capital letter. So I would rename the entity names to Flight and ItineraryTraveller .

Note that in some cases the @JoinColumn on the child object must have insertable = false and updatable = false like this: @JoinColumn(name = "user_id", insertable = false, updatable = false)

public class User {
   private List<UserRole>   roles;

   @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "user")
   public List<UserRole> getRoles() {
      return this.roles;
   }
   public void setRoles(List<UserRole> roles) {
       this.roles = roles;
   }

}

public class UserRole {
    @ManyToOne
    @JoinColumn(name = "user_id", insertable = false, updatable = false)
    private User user;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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