使用复合键时出现 JpaSystemException
JpaSystemException when using composite key
我正在构建一个 spring 引导应用程序,但我遇到了 JpaSystemException: attempted to assign id from null one-to-one property
错误。让我给你一些关于这个项目的细节。
首先,我有以下数据库模式
describe airports;
+--------------------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------+------------+------+-----+---------+-------+
| airport_id | int(11) | NO | PRI | NULL | |
| airport_name | text | NO | | NULL | |
+--------------------------+------------+------+-----+---------+-------+
describe flights;
+------------------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+---------+------+-----+---------+-------+
| flight_from_airport_id | int(11) | NO | PRI | NULL | |
| flight_to_airport_id | int(11) | NO | PRI | NULL | |
| flight_type | int(11) | NO | PRI | NULL | |
+------------------------+---------+------+-----+---------+-------+
基本上,table 航班用于存储从一个机场到另一个机场的航班数据。
我有两个实体;机场及航班如下:
Airport.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "airports")
public class Airport {
@Id
@Column(name="airport_id")
private int airportId;
@Column(name="airport_name")
private String airportName;
//Getters and Setters
public Airport(int airportId, String airportName) {
this.airportId = airportId;
this.airportName = airportName;
}
}
Flight.java
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
@Entity
@Table(name = "flights")
public class Flight {
@EmbeddedId
FlightPrimaryKey flightPrimaryKey;
@MapsId("fromAirport")
@ManyToOne
@JoinColumn(name = "flightFromAirportId")
private Airport fromAirport;
@MapsId("toAirport")
@ManyToOne
@JoinColumn(name = "flightToAirportId")
private Airport toAirport;
@Column(name="flight_type")
private int flightType;
//Getters and Setters
public Flight(FlightPrimaryKey flightPrimaryKey, int flightType) {
this.flightPrimaryKey = flightPrimaryKey;
this.flightType = flightType;
}
}
因为我想要 class 航班的组合键,所以我有一个 ID class。
FlightId.java
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class FlightId implements Serializable {
@Column(name = "flight_from_airport_id")
private int fromAirport;
@Column(name = "flight_to_airport_id")
private int toAirport;
// Getters and Setters, hashcode, equals
public TransferPrimaryKey(int fromAirport, int toAirport) {
this.fromAirport = fromAirport;
this.toAirport = toAirport;
}
}
然后我有一个 JPA 存储库
FlightRepository.java
public interface FlightRepository extends JpaRepository<Flight, FlightId>{}
为了测试以上内容,我使用以下代码:
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class FlightTest {
@Autowired
private AiportRepository airportRepository;
@Autowired
private FlightRepository flightRepository;
@Test
public void shouldStoreAFlight() {
Airport fromAirport = airportRepository.save(new Airport(1, "LAX");
Airport toAirport = airportRepository.save(new Airport(2, "JFK")
FlightId flightId = new FlightId(fromAirport.getId(), toAirport.getId());
Flight flight = flightRepository.save(new Flight(flightId, 1));
}
}
当我运行上面的代码时,我得到了JpaSystemException。我也不明白为什么错误说一对一 属性。我只定义了一个多对一属性。显然我错过了一些东西。
解决方案应该是设置您的引用:
public void shouldStoreAFlight() {
Airport fromAirport = airportRepository.save(new Airport(1, "LAX");
Airport toAirport = airportRepository.save(new Airport(2, "JFK")
FlightId flightId = new FlightId(fromAirport.getId(), toAirport.getId());
Flight flight = new Flight(flightId, 1);
flight.setFromAirport(fromAirport);
flight.setToAirport(toAirport);
flight = flightRepository.save(flight);
}
应该不需要使用上面的代码设置 FlightId 中的值,但我保留它以匹配您的构造函数,并且因为您将它们设置为 int 而不是一个允许空值的整数。
我正在构建一个 spring 引导应用程序,但我遇到了 JpaSystemException: attempted to assign id from null one-to-one property
错误。让我给你一些关于这个项目的细节。
首先,我有以下数据库模式
describe airports;
+--------------------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------+------------+------+-----+---------+-------+
| airport_id | int(11) | NO | PRI | NULL | |
| airport_name | text | NO | | NULL | |
+--------------------------+------------+------+-----+---------+-------+
describe flights;
+------------------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+---------+------+-----+---------+-------+
| flight_from_airport_id | int(11) | NO | PRI | NULL | |
| flight_to_airport_id | int(11) | NO | PRI | NULL | |
| flight_type | int(11) | NO | PRI | NULL | |
+------------------------+---------+------+-----+---------+-------+
基本上,table 航班用于存储从一个机场到另一个机场的航班数据。
我有两个实体;机场及航班如下:
Airport.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "airports")
public class Airport {
@Id
@Column(name="airport_id")
private int airportId;
@Column(name="airport_name")
private String airportName;
//Getters and Setters
public Airport(int airportId, String airportName) {
this.airportId = airportId;
this.airportName = airportName;
}
}
Flight.java
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
@Entity
@Table(name = "flights")
public class Flight {
@EmbeddedId
FlightPrimaryKey flightPrimaryKey;
@MapsId("fromAirport")
@ManyToOne
@JoinColumn(name = "flightFromAirportId")
private Airport fromAirport;
@MapsId("toAirport")
@ManyToOne
@JoinColumn(name = "flightToAirportId")
private Airport toAirport;
@Column(name="flight_type")
private int flightType;
//Getters and Setters
public Flight(FlightPrimaryKey flightPrimaryKey, int flightType) {
this.flightPrimaryKey = flightPrimaryKey;
this.flightType = flightType;
}
}
因为我想要 class 航班的组合键,所以我有一个 ID class。
FlightId.java
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class FlightId implements Serializable {
@Column(name = "flight_from_airport_id")
private int fromAirport;
@Column(name = "flight_to_airport_id")
private int toAirport;
// Getters and Setters, hashcode, equals
public TransferPrimaryKey(int fromAirport, int toAirport) {
this.fromAirport = fromAirport;
this.toAirport = toAirport;
}
}
然后我有一个 JPA 存储库
FlightRepository.java
public interface FlightRepository extends JpaRepository<Flight, FlightId>{}
为了测试以上内容,我使用以下代码:
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class FlightTest {
@Autowired
private AiportRepository airportRepository;
@Autowired
private FlightRepository flightRepository;
@Test
public void shouldStoreAFlight() {
Airport fromAirport = airportRepository.save(new Airport(1, "LAX");
Airport toAirport = airportRepository.save(new Airport(2, "JFK")
FlightId flightId = new FlightId(fromAirport.getId(), toAirport.getId());
Flight flight = flightRepository.save(new Flight(flightId, 1));
}
}
当我运行上面的代码时,我得到了JpaSystemException。我也不明白为什么错误说一对一 属性。我只定义了一个多对一属性。显然我错过了一些东西。
解决方案应该是设置您的引用:
public void shouldStoreAFlight() {
Airport fromAirport = airportRepository.save(new Airport(1, "LAX");
Airport toAirport = airportRepository.save(new Airport(2, "JFK")
FlightId flightId = new FlightId(fromAirport.getId(), toAirport.getId());
Flight flight = new Flight(flightId, 1);
flight.setFromAirport(fromAirport);
flight.setToAirport(toAirport);
flight = flightRepository.save(flight);
}
应该不需要使用上面的代码设置 FlightId 中的值,但我保留它以匹配您的构造函数,并且因为您将它们设置为 int 而不是一个允许空值的整数。