开发者社区> 问答> 正文

使用jpa和休眠问题的JoiningTables是mulitmapping失败的

我两个月前才刚刚开始学习Java ee,并且在某些方面都在挣扎中,如下所示。在完成一些逻辑后,我为预订系统提供了三个实体类,并且在运行项目时遇到了麻烦:

@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.springmvc.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]描述符:

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

我了解到映射中存在问题,我对此进行了一些研究,但仍然无法了解如何解决它或如何建立实体类之间的关系。谁能帮助我找出问题并解决。

数据库表:

 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;

问题来源:Stack Overflow

展开
收起
montos 2020-03-23 19:02:13 544 0
1 条回答
写回答
取消 提交回答
  • 预订实体。

    @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-link将使用字段名称,因此,在这种情况下,您将具有2个指向同一列的java属性。

    @JoinColumn为您完成肮脏的工作(引用另一个引用SQL表的实体),这就是为什么我们使用JPA。

    我将代表主键的字段从int更改为Integer类。您可以在这里找到原因:JPA(休眠)列映射中的原始类和包装器类有什么区别

    回答来源:Stack Overflow

    2020-03-23 19:03:59
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载