Объединение таблиц, использующих jpa и hibernate, является проблемой с многоадресным отображением. - PullRequest
1 голос
/ 15 марта 2020

Я только начал изучать java ее два месяца go, и я борюсь в некоторых частях, как показано ниже. У меня есть три класса сущностей для системы бронирования, и я испытываю трудности с запуском проекта после того, как выполнил некоторые логи c:

     @Entity
     @Table(name="booking")
     public class Booking implements Serializable {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private int reservationId;
     private String stateroomType;
     private double totalAmount;
     private int totalGuests;   
     private int shipId;
     private int passId;

  //Joining Tables
  @OneToOne
  @JoinColumn(name="passId")
  private Passenger passenger;

  @ManyToOne
  @JoinColumn(name="shipId")
  private Cruise cruise;

    @Entity
     @Table(name = "shipcruise")
    public class Cruise implements Serializable {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int cruiseId;
    private String cruiseName;
    private LocalDate startDate;
    private LocalDate endDate;
    private Timestamp destination;

    @Entity
    @Table(name = "passengers")
    public class Passenger implements Serializable{

    @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int passengerId;
    private String userName;
    private String firstname;
    private String lastname;
    private String address;
    private String city;
    private String country;
    private String postalCode;
    private String password;

Когда я запускаю свой проект, я получаю это сообщение об ошибке:

Исключение [EclipseLink-48] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DescriptorException Исключение Описание: для поля [booking.SHIPID] существует несколько доступных для записи сопоставлений. Только один может быть определен как доступный для записи, все остальные должны быть указаны только для чтения. Отображение: org.eclipse.persistence.mappings.OneToOneMapping [cruise] Дескриптор: RelationalDescriptor (com.spring mvc .jpa.booking.Booking -> [DatabaseTable (booking)]) Исключение [EclipseLink-48] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DescriptorException Исключение Описание: для поля [booking.PASSID] существует несколько сопоставлений с возможностью записи. Только один может быть определен как доступный для записи, все остальные должны быть указаны только для чтения. Сопоставление: org.eclipse.persistence.mappings.OneToOneMapping [passenger] Дескриптор: RelationalDescriptor (com.spring mvc .jpa.booking.Booking -> [DatabaseTable (booking)])

. .................................................. ..............................................

Я понимаю, что в отображении есть проблема, и я провел ее исследование, но все еще не могу понять, как ее решить или как установить связь между классами сущностей. Может кто-нибудь помочь мне разобраться в проблеме и решить ее.

Таблицы базы данных:

      CREATE TABLE `booking` (
     `reservationId` int NOT NULL,
     `stateroomType` varchar(30) NOT NULL,
     `totalGuests` int NOT NULL,
     `totalAmount` decimal(10,2) NOT NULL,
     `passId` int DEFAULT NULL,
     `shipId` int DEFAULT NULL,
      PRIMARY KEY (`reservationId`),
      KEY `passId` (`passId`),
      KEY `shipId` (`shipId`),
      CONSTRAINT `booking_ibfk_1` FOREIGN KEY (`passId`) REFERENCES 
      `passengers` (`passengerId`),
      CONSTRAINT `booking_ibfk_2` FOREIGN KEY (`shipId`) REFERENCES 
      `shipcruise` (`cruiseId`)
       ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

      CREATE TABLE `passengers` (
     `passengerId` int NOT NULL AUTO_INCREMENT,
     `userName` varchar(50) DEFAULT NULL,
     `password` varchar(25) DEFAULT NULL,
     `firstname` varchar(30) DEFAULT NULL,
     `lastname` varchar(30) DEFAULT NULL,
     `address` varchar(255) DEFAULT NULL,
    `city` varchar(25) DEFAULT NULL,
    `postalCode` varchar(10) DEFAULT NULL,
     `country` varchar(20) DEFAULT NULL,
     PRIMARY KEY (`passengerId`)
     ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 
   COLLATE=utf8mb4_0900_ai_ci;

    CREATE TABLE `shipcruise` (
   `cruiseId` int NOT NULL AUTO_INCREMENT,
   `CruiseName` varchar(50) DEFAULT NULL,
   `shipName` varchar(50) DEFAULT NULL,
  `startDate` date NOT NULL,
  `endDate` date NOT NULL,
   `destination` timestamp NOT NULL,
   PRIMARY KEY (`cruiseId`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

1 Ответ

0 голосов
/ 16 марта 2020

Бронирующий объект.

 @Entity
 @Table(name="booking")
 public class Booking implements Serializable {
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Integer reservationId;
 private String stateroomType;
 private double totalAmount;
 private int totalGuests;   

 //Joining Tables
 @ManyToOne
 @JoinColumn(name="passId")
 private Passenger passenger;

 @ManyToOne
 @JoinColumn(name="shipId")
 private Cruise cruise;

Круизный объект.

@Entity
@Table(name = "shipcruise")
public class Cruise implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer cruiseId;
private String cruiseName;
private LocalDate startDate;
private LocalDate endDate;
private Timestamp destination;

Пассажирский объект.

@Entity
@Table(name = "passengers")
public class Passenger implements Serializable{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer passengerId;
private String userName;
private String firstname;

В вашем коде есть:

 private int shipId;
 private int passId;

и ниже, у вас есть:

  //Joining Tables
  @OneToOne
  @JoinColumn(name="passId")
  private Passenger passenger;

  @ManyToOne
  @JoinColumn(name="shipId")
  private Cruise cruise;

Когда вы не используете @Column или @JoinColumn, ссылка на eclipse будет использовать имя поля, поэтому в этом случае вы будет иметь 2 java свойства, которые указывают на тот же столбец.

@ JoinColumn делает грязную работу за вас (ссылается на другую сущность, которая ссылается на таблицу SQL), поэтому мы используем JPA.

Я изменил поля, представляющие первичный ключ, с int на класс Integer. Вы можете найти причину здесь: В чем разница между примитивом и классом-оберткой в ​​отображениях столбцов JPA (Hibernate)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...