1

When i tried to map class with 2 referenced columns, I got this error:

Caused by: java.lang.ClassCastException: entities.Client cannot be cast to java.io.Serializable

I read some similar question When and why JPA entities should implement Serializable interface?

And i saw this answer:

It has one more parameters named referencedColumnName. This parameter declares the column in the targeted entity that will be used to the join. Note that when using referencedColumnName to a non primary key column, the associated class has to be Serializable.

1.Why? whats happening in the background?

@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;

When i execute the code:

 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();

    }



The exception:

 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

After i know that i have to implement Serializable (not only for good practice) How do i have to do that?

2. The subclasses has to implement Serializable? or only the superclass?

3. Do i have to declare serialVersionUID?

4. If the subclasses has to implement Serializable, They has to declare serialVersionUID?

Agar123
  • 95
  • 7
  • 1
    When asking about an exception, post the code causing the exception, and the complete and exact stack trace of the exception. Entities don't need to implement Serializable. The problem is caused by a bug in your code, but you haven't posted it, so we can't help. – JB Nizet Oct 14 '19 at 19:05
  • I edited the question, Thanks. – Agar123 Oct 14 '19 at 19:18
  • 1
    Post the complete (from line 0 to last line) code of your two entities and of your superclass. And you should really not save the full name of the client in reservation. It's already in Client, and the reservation has an association to the client. So it's redundant. And doing that also prevents you from ever changing the full name of a client. Believe me: it will happen. – JB Nizet Oct 14 '19 at 19:28
  • I edited, But if i want to use method like getAllReservations not only for one client, i want his name beside the reservation, And i dont want to get all the details about the clients, How do i get only the full name? – Agar123 Oct 14 '19 at 19:40
  • 1
    By using queries with joins. If tomorrow, your client asks to displaythe client full name, and also his email, address and phone number, you won't duplicate all the columns of clients into reservation, will you? – JB Nizet Oct 14 '19 at 19:57
  • No, you right, I dont have to do that. You helped me so much, Thank you. – Agar123 Oct 14 '19 at 20:19

0 Answers0