JPA 持久性 CrudRepository.save() 语法错误

JPA persistence CrudRepository.save() syntax error

我在航空公司管理系统上工作,我通过 JPA CrudRepository 方法访问 mysql 数据库。 每当我尝试使用 repository.save(flightObject) 将航班对象保存到数据库中时,它会抛出以下错误 -

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'from, capacity, manufacturer, model, plane, yearofmanufacture, price, seatsleft,' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5098)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)

我的航班创建函数如下-

    @RequestMapping(method = RequestMethod.POST, value = "/flight/{flight_number}")
        public Flight createUpdateFlight(@PathVariable(value = "flight_number") String flightNumber, @RequestParam(value="price") int price, @RequestParam(value="from") String from, @RequestParam(value="to") String to, @RequestParam(value="departuretime") String departuretime, @RequestParam(value="arrivaltime") String arrivaltime,@RequestParam(value="seatsleft") int seatsleft, @RequestParam("description") String description, @RequestParam(value="capacity") int capacity, @RequestParam(value="manufacturer") String manufacturer,@RequestParam(value="model") String model,@RequestParam(value="yearofmanufacture") String yearofmanufacture) throws ParseException {

            DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
            Date arrivaldate = format.parse(arrivaltime);
            Date departuredate = format.parse(departuretime);

            Plane plane = new Plane(capacity,model,manufacturer,yearofmanufacture);

            Flight flight = new Flight(flightNumber, price, from, to, departuredate, arrivaldate, seatsleft, description, plane, null);

            try{
                flightRepository.save(flight);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }

            return flightRepository.findBynumber(flight.getNumber());
        }

我的航班资料库class -

@Repository
@Transactional
public interface FlightRepository extends CrudRepository<Flight, String> {
    Flight findBynumber(String number);
}

我的航班实体class如下-

@Entity
@Table(name = "flight")
@XmlRootElement
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class Flight {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "number")
    private String number; // Each flight has a unique flight number.

    @Column(name = "price")
    private int price;

    @Column(name = "from")
    private String from;

    @Column(name = "to")
    private String to;

    @Column(name = "departuretime")
    private Date departureTime;

    @Column(name = "arrivaltime")
    private Date arrivalTime;

    @Column(name = "description")
    private String description;

    @Column(name = "seatsleft")
    private int seatsLeft;


    //@OneToOne(fetch=FetchType.LAZY)
    //@JoinColumn(name="plane")
    @Embedded
    private Plane plane; // Embedded


    @OneToMany()
    @JoinTable(
              name="passenger_list",
              joinColumns=
                { @JoinColumn(name="number") },//, referencedColumnName="number"),
              inverseJoinColumns=
                 @JoinColumn(name="passenger" , referencedColumnName="id" ))
    private List<Passenger> passengers;


    public Flight(String number, int price, String from, String to, Date departureTime, Date arrivalTime,
            int seatsLeft, String description, Plane plane, List<Passenger> passengers) {
        super();
        System.out.println("Inside Flight constr");
        this.number = number;
        this.price = price;
        this.from = from;
        this.to = to;
        this.departureTime = departureTime;
        this.arrivalTime = arrivalTime;
        this.description = description;
        this.seatsLeft = seatsLeft;
        this.plane = plane;
        this.passengers = passengers;
    }


    public Flight()
    {
        super();
    }

    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public String getFrom() {
        return from;
    }
    public void setFrom(String from) {
        this.from = from;
    }
    public String getTo() {
        return to;
    }
    public void setTo(String to) {
        this.to = to;
    }
    public Date getDepartureTime() {
        return departureTime;
    }
    public void setDepartureTime(Date departureTime) {
        this.departureTime = departureTime;
    }
    public Date getArrivalTime() {
        return arrivalTime;
    }
    public void setArrivalTime(Date arrivalTime) {
        this.arrivalTime = arrivalTime;
    }
    public int getSeatsLeft() {
        return seatsLeft;
    }
    public void setSeatsLeft(int seatsLeft) {
        this.seatsLeft = seatsLeft;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Plane getPlane() {
        return plane;
    }
    public void setPlane(Plane plane) {
        this.plane = plane;
    }

    public List<Passenger> getPassengers() {
        return passengers;
    }
    public void setPassengers(List<Passenger> passengers) {
        this.passengers = passengers;
    }
}

我的可嵌入平面class如下-

@Embeddable
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Plane implements Serializable{

    //@Id
    @Column(name = "plane")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int plane;

    @Column(name = "capacity")
    private int capacity;

    @Column(name = "model")
    private String model;

    @Column(name = "manufacturer")
    private String manufacturer;

    @Column(name = "yearofmanufacture")
    private String yearofmanufacture;


    public Plane(int capacity, String model, String manufacturer, String yearofmanufacture) {
        super();
        System.out.println("Inside Plane constr");
        this.capacity = capacity;
        this.model = model;
        this.manufacturer = manufacturer;
        this.yearofmanufacture = yearofmanufacture;
    }

    public Plane() {
        super();
    }

    public int getId() {
        return plane;
    }

    public void setId(int id) {
        this.plane = id;
    }

    public int getCapacity() {
        return capacity;
    }

    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public String getManufacturer() {
        return manufacturer;
    }

    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }

    public String getYearofmanufacture() {
        return yearofmanufacture;
    }

    public void setYearofmanufacture(String yearofmanufacture) {
        this.yearofmanufacture = yearofmanufacture;
    }

}

这是我的数据库模式图像 -

如果您能发现任何错误,请告诉我。 我已经安静地尝试了一段时间,但没有成功。 我们可以在执行前打印 JPA 查询以检查语法吗?

很高兴看到您的 FlightRepository 结构。 我认为 'findBynumber' 方法有一个错误,在语法上不能转换为写查询。 它应该看起来像 'findByNumber'.

试试这个

@RequestMapping(method = RequestMethod.POST, value = "/flight/{flight_number}")
public Flight createUpdateFlight(@PathVariable(value = "flight_number") String flightNumber, @RequestParam(value="price") int price, @RequestParam(value="from") String from, @RequestParam(value="to") String to, @RequestParam(value="departuretime") String departuretime, @RequestParam(value="arrivaltime") String arrivaltime,@RequestParam(value="seatsleft") int seatsleft, @RequestParam("description") String description, @RequestParam(value="capacity") int capacity, @RequestParam(value="manufacturer") String manufacturer,@RequestParam(value="model") String model,@RequestParam(value="yearofmanufacture") String yearofmanufacture) throws ParseException {

    DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
    Date arrivaldate = format.parse(arrivaltime);
    Date departuredate = format.parse(departuretime);

    Plane plane = new Plane(capacity,model,manufacturer,yearofmanufacture);

    Flight flight = new Flight(flightNumber, price, from, to, departuredate, arrivaldate, seatsleft, description, plane, null);

    try{
        flight = flightRepository.save(flight); //save() method returns a Flight entity after saving it.
    }
    catch(Exception e){
        e.printStackTrace();
    }

    return flight;
}

PS: 我没有测试过这个。

问题已解决。问题出在 'from' 和 'to' 属性上。 'from' 和 'to' 是数据库关键字,因此不能直接用作 JPA 实体中的列名。 直接在查询中使用它们会使它无效。 更改列名就可以了。 另一种选择是在编写查询时将列名用引号括起来,这样它们就不会被视为关键字。