当我尝试用2个引用的列映射类时,出现此错误:
由以下原因引起:java.lang.ClassCastException:实体。客户端不能为 强制转换为java.io.Serializable
我读了类似的问题When and why JPA entities should implement Serializable interface?
我看到了这个答案:
它还有一个名为referencedColumnName的参数。这个参数 在目标实体中声明将用于 加入。请注意,当对非主键使用referencedColumnName时 列,关联的类必须是可序列化的。
1。为什么?后台发生了什么事?
@MappedSuperclass
public abstract class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "full_name")
private String fullName;
private String email;
@Column(name = "phone_number")
private String phoneNumber;
private String address;
public Person()
{
}
public Person(String fullName, String phoneNumber, String email, String address )
{
this.fullName = fullName;
this.email = email;
this.phoneNumber = phoneNumber;
this.address = address;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
@Entity
@Table(name = "CLIENTS")
public class Client extends Person {
@OneToMany(mappedBy = "client", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Reservation> reservations = new ArrayList<>();
public Client() {
}
public Client(String fullName, String phoneNumber, String email, String address) {
super(fullName, phoneNumber, email, address);
}
public List<Reservation> getReservations() {
return reservations;
}
public void addReservation(Reservation reservation) {
this.reservations.add(reservation);
reservation.setClient(this);
}
public void removeReservation(Reservation reservation) {
this.getReservations().remove(reservation);
reservation.setClient(null);
}
}
@Entity
@Table(name = "SUPPLIERS")
public class Supplier extends Person {
@OneToMany(mappedBy = "supplier", cascade = CascadeType.ALL, orphanRemoval = true)
private List<SupplierItem> items = new ArrayList<>();
public Supplier() {
}
public Supplier(String fullName, String phoneNumber,
String email, String address) {
super(fullName, phoneNumber, email, address);
}
public List<SupplierItem> getItems() {
return items;
}
public void addItem(SupplierItem item) {
this.getItems().add(item);
item.setSupplier(this);
}
public void removeItem(SupplierItem item) {
this.getItems().remove(item);
item.setSupplier(null);
}
}
public class Reservation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "reservation_id")
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumns({
@JoinColumn(name = "client_id", referencedColumnName="id"),
@JoinColumn(name = "client_full_name", referencedColumnName="full_name")})
private Client client;
当我执行代码时:
Client client = new Client("Benny Hagadol", "0523612324","Bennyhagadol@gmail.com","Florentin 34 Tel Aviv");
Reservation re = new Reservation();
client.addReservation(re);
new ClientManager().addClient(client);
public void addClient(Client client) {
this.em.getTransaction().begin();
this.em.persist(client);
this.em.getTransaction().commit();
}
例外:
14, 2019 10:10:32 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate:
insert
into
CLIENTS
(address, email, full_name, phone_number)
values
(?, ?, ?, ?)
Hibernate:
insert
into
RESERVATIONS
(client_id, client_full_name, created_on, date_to_supply, last_updated, total_sum)
values
(?, ?, ?, ?, ?, ?)
Exception in thread "main" javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:81)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104)
at managers.ClientManager.addClient(ClientManager.java:31)
at GUI.Menu.main(Menu.java:148)
Caused by: java.lang.ClassCastException: entities.Client cannot be cast to java.io.Serializable
at org.hibernate.type.CollectionType.getKeyOfOwner(CollectionType.java:446)
at org.hibernate.engine.internal.Collections.processReachableCollection(Collections.java:166)
at org.hibernate.event.internal.FlushVisitor.processCollection(FlushVisitor.java:50)
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65)
at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:182)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:233)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:93)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:108)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1358)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:436)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3235)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2403)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
... 2 more
在我知道自己必须实现Serializable之后(不仅出于良好实践) 我该怎么做?
2。子类必须实现Serializable?还是只有超类?
3。我必须声明serialVersionUID吗?
4。如果子类必须实现Serializable,则必须声明serialVersionUID?