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 实体中的列名。
直接在查询中使用它们会使它无效。
更改列名就可以了。
另一种选择是在编写查询时将列名用引号括起来,这样它们就不会被视为关键字。
我在航空公司管理系统上工作,我通过 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 实体中的列名。 直接在查询中使用它们会使它无效。 更改列名就可以了。 另一种选择是在编写查询时将列名用引号括起来,这样它们就不会被视为关键字。