0

I'm using Hibernate, MySQL, Spring MVC.

My current job is booking a flight ticket.

I got a flight schedule entity from path variable. And, I got a passenger entity from HttpSession.

Below is the controller code:

@RequestMapping("/booking/{results[0].flightscheduleId}")
public String bookBoardingPass
    (@PathVariable("results[0].flightscheduleId") Integer flightId, HttpSession session) {

    Passenger passenger = (Passenger) session.getAttribute("user");
    FlightSchedule flightSchedule = this.flightScheduleService.get(flightId);

    this.boardingPassService.booking(flightSchedule, passenger);

    return "search";
}

Below is booking method code:

@Override 
public void booking (FlightSchedule flightSchedule, Passenger passenger) {

    BoardingPass ticket = new BoardingPass();
    ticket.setFlightschedule(flightSchedule);
    ticket.setPassenger(passenger);

    System.out.println("flight id: "+flightSchedule.getFlightscheduleId());
    System.out.println("passenger id: "+passenger.getPassengerId());

    this.persist(ticket);
    //sessionFactory.getCurrentSession().saveOrUpdate(ticket);
}

in booking method, I can print both flightSchedule's id and passenger's id.

But, when I execute 'persist' method, it says Field 'flightschedule_id' doesn't have a default value

In the persist method, it runs sessionFactory.getCurrentSession().saveOrUpdate(ticket);

  • flightschedule_id is a primary key, auto-increment, not-null.

I cannot give it a default value. Also, I check STRICT mode(?) on phpmyadmin through googling search result. (I am not sure I do well. Anyway it didn't work).

How can I solve this problem?

EDIT:

Below is BoardingPass class:

@Entity
@Table
public class BoardingPass implements java.io.Serializable {

private Integer boardingpassId;
private FlightSchedule flightschedule;
private Passenger passenger;

public BoardingPass() {
}

public BoardingPass(FlightSchedule flightschedule, Passenger passenger) {
    this.flightschedule = flightschedule;
    this.passenger = passenger;
}

@Id
@GeneratedValue(strategy = IDENTITY)

@Column(name = "id", unique = true, nullable = false)
public Integer getBoardingpassId() {
    return this.boardingpassId;
}

public void setBoardingpassId(Integer boardingpassId) {
    this.boardingpassId = boardingpassId;
}

@ManyToOne
@MapsId("flightscheduleId")
public FlightSchedule getFlightschedule() {
    return this.flightschedule;
}

public void setFlightschedule(FlightSchedule flightschedule) {
    this.flightschedule = flightschedule;
}

@ManyToOne
@MapsId("passengerId")
public Passenger getPassenger() {
    return this.passenger;
}

public void setPassenger(Passenger passenger) {
    this.passenger = passenger;
}


}

Just in case, I add part of FlightSchedule and Passenger class.

Below is FlightSchedule.java :

@Entity
@Table
public class FlightSchedule implements java.io.Serializable {

private Integer flightscheduleId;
private Date depDay;
private Date depTime;
private Date arrDay;
private Date arrTime;
private Double flightTime;
private Integer price;
private Set<BoardingPass> boardingPasses = new HashSet<BoardingPass>(0);
private Airplane airplane;
private Airport depAirport;
private Airport arrAirport;

public FlightSchedule() {
}

public FlightSchedule(Date depDay, Date depTime, Date arrDay, Date arrTime, Integer price) {
    this.depDay = depDay;
    this.depTime = depTime;
    this.arrDay = arrDay;
    this.arrTime = arrTime;
    this.price = price;
}

public FlightSchedule(Date depDay, Date depTime, Date arrDay, Date arrTime, Double flightTime, Integer price,
        Set<BoardingPass> boardingPasses, Airplane airplane, Airport depAirport, Airport arrAirport) {
    this.depDay = depDay;
    this.depTime = depTime;
    this.arrDay = arrDay;
    this.arrTime = arrTime;
    this.flightTime = flightTime;
    this.price = price;
    this.boardingPasses = boardingPasses;
    this.airplane = airplane;
    this.depAirport = depAirport;
    this.arrAirport = arrAirport;
}

@Id
@GeneratedValue(strategy = IDENTITY)

@Column(name = "id", unique = true, nullable = false)
public Integer getFlightscheduleId() {
    return this.flightscheduleId;
}

public void setFlightscheduleId(Integer flightscheduleId) {
    this.flightscheduleId = flightscheduleId;
}

@OneToMany(mappedBy = "flightschedule", cascade = CascadeType.ALL, orphanRemoval = true)
public Set<BoardingPass> getBoardingPasses() {
    return this.boardingPasses;
}

public void setBoardingPasses(Set<BoardingPass> boardingPasses) {
    this.boardingPasses = boardingPasses;
}


.... getters and setters... 

} 

Below is Passenger.java:

@Entity
@Table
public class Passenger implements java.io.Serializable {

private Integer passengerId;
private String password;
private String passportNo;
private String passengerName;
private Date birth;
private Integer mileage;
private String contact;
private Set<BoardingPass> boardingPasses = new HashSet<BoardingPass>(0);

public Passenger() {
}

public Passenger(String password, String passportNo, Date birth, Integer mileage) {
    this.password = password;
    this.passportNo = passportNo;
    this.birth = birth;
    this.mileage = mileage;
}

public Passenger(String password, String passportNo, String passengerName, Date birth, Integer mileage, String contact, Set<BoardingPass> boardingPasses) {
    this.password = password;
    this.passportNo = passportNo;
    this.passengerName = passengerName;
    this.birth = birth;
    this.mileage = mileage;
    this.contact = contact;
    this.boardingPasses = boardingPasses;
}

@Id
@GeneratedValue(strategy = IDENTITY)

@Column(name = "id", unique = true, nullable = false)
public Integer getPassengerId() {
    return this.passengerId;
}

public void setPassengerId(Integer passengerId) {
    this.passengerId = passengerId;
}

@OneToMany(mappedBy = "passenger", cascade = CascadeType.ALL, orphanRemoval = true)
public Set<BoardingPass> getBoardingPasses() {
    return this.boardingPasses;
}

public void setBoardingPasses(Set<BoardingPass> boardingPasses) {
    this.boardingPasses = boardingPasses;
}


.... getters and setters...

}
Lee
  • 11
  • 7

2 Answers2

1

The first thing that i see completely wrong with that mapping is the @MapsId annotations:

Those are used to tell hibernate the attribute within a composite key to which the relationship attribute corresponds.

Meaning without a composite primary key it doesn't make any sense and i suspect it's messing up your mappings... try to remove them and see how it goes

A simple example http://www.objectdb.com/api/java/jpa/MapsId

P.s. i was forgetting you need to add the @JoinColumn annotations too to the mappings

@JoinColumn(name = "flightschedule_id", referencedColumnName = "boardingPass_id")

Edit: Also the thing causing the problem in the first place is that you specified the name of the db column wrong

@Column(name = "id", unique = true, nullable = false)
public Integer getFlightscheduleId() {
    return this.flightscheduleId;
}

shouldn't that be @Column(name = "flightschedule_id", unique = true, nullable = false) ?

same things for the other 2 entities as well check that the @Column name attribute correspond to db column name

Zeromus
  • 4,472
  • 8
  • 32
  • 40
  • You mean I have to remove the `@MapsId` and add `@JoinColumn` line instead, right? – Lee Dec 05 '17 at 10:14
  • @Lee yeah the MapsId make no sense here and the JoinColumn tells hibernate how to map the foreign key. the name and referencedColumnName are the column name in db – Zeromus Dec 05 '17 at 10:15
  • oh i'm an idiot i missed the simpler error, editing now – Zeromus Dec 05 '17 at 10:19
  • I switched all the `@MapsId` to `@JoinColumn` , and all the `id` to `tablename_id`. But I cannot run because of this error. Invocation of init method failed; nested exception is org.hibernate.MappingException: Unable to find column with logical name: boardingpass_id in org.hibernate.mapping.Table(lee.flight_schedule) ` – Lee Dec 05 '17 at 10:43
  • same thing... you didn't just copy paste in all entity without changing name right? obviously BoardingPass entity need boardingPass_id or however its called that column in your database etc – Zeromus Dec 05 '17 at 10:46
  • Yep I typed myself. If the table DB name is 'flight_schedule' then I changed 'id' to 'flight_schedule_id'. Is it wrong? – Lee Dec 05 '17 at 10:48
  • you are missing the point... if your table "randomTable" has a pk column called "qwerty" you have to let hibernate know what that column name is so @Column(name = "qwerty") – Zeromus Dec 05 '17 at 10:50
0

If you didn't specify PRIMARY KEY column as AUTO_INCREMENT then you have to give values manually in your Database. Make your flightschedule_id column which is the Primary key as AUTO_INCREMENT then it should work. Hope this will help. Thank you.

Harshit Gupta
  • 106
  • 4
  • 16
  • "flightschedule_id is a primary key, auto-increment, not-null." he said they are specified... – Zeromus Dec 05 '17 at 09:31
  • `desc flight_schedule;` command confirms that the primary key is set to auto_increment. – Lee Dec 05 '17 at 09:42