【问题标题】:JPA Entities Generating Wrong Database DesignJPA 实体生成错误的数据库设计
【发布时间】:2015-07-19 08:09:40
【问题描述】:

在我的项目中,管理员(用户)可以设置为接收有关他选择的任何用户的预定电子邮件。

我需要一个如下设计的数据库:

TABLE User (
    UserId INT PRIMARY KEY AUTO_INCREMENT,
    Email VARCHAR,
    FirstName VARCHAR,
    LastName VARCHAR
    IsAdmin BOOL,
    ...
)

TABLE Email_Schedule (
    ScheduleId INT PRIMARY KEY AUTO_INCREMENT, /* this is not necessary */
    AdminId INT, /* could be replaced by a composite foreign primary keys */
    UserId INT,
    FOREIGN KEY (AdminId) REFERENCES User (UserId),
    FOREIGN KEY (UserId) REFERENCES User (UserId)
)

JPA 实体的 Java 类中的以下代码:

@Entity
public class Email_Schedule {
   @Id
   private int scheduleId;

   @ManyToOne(targetEntity = User.class)
   private List<User> admins = new LinkedList<>();

   @ManyToOne(targetEntity = User.class)
   private List<User> users = new LinkedList<>();

   public Email_Schedule() {
    super();
   }

   public Email_Schedule(User admin, User user) {
      super();
      this.admins.add(admin);
      this.users.add(user);
   }
   // setters and getters...

生成以下架构的数据库:

 TABLE USER (
     ...
 )
 TABLE SCHEDULE (
     ScheduleId INT PRIMARY KEY AUTO_INCREMENT
 )
 TABLE Email_Schedule (
     ScheduleId INT,
     Users INT,
     Admins INT,
     FOREIGN KEY (ScheduleId) REFERENCES SCHEDULE(ScheduleId),
     FOREIGN KEY (Users) REFERENCES USER (UserId),
     FOREIGN KEY (Admins) REFERENCES USER (UserId)
 )

我的问题是为什么它为ScheduleId创建了一个无用的表并从另一个表中引用它而不是直接在Email_Schedule表中使用它?

问题似乎出在ScheduleId 上。我试图通过创建IdClass 不使用它,但我遇到了不同的错误和错误的数据库设计。

【问题讨论】:

  • 你用什么工具来生成ddl?
  • @DraganBozanovic Eclipse,JPA 工具,从实体生成表。然后,我在 MySQL 工作台中检查了生成的表。
  • 可以直接用hbm2ddl试试吗?
  • 恕我直言,您的设计错误与列表结构有关,Email_Schedule 类型的对象(实例)应该与用户和管理员具有一对一(一对多)关系。跨度>
  • @rz3r0:但您的问题之上的要求禁止这种方法。它为每个用户和管理员定义了一个 scheduleId。

标签: java mysql jpa


【解决方案1】:

EclipseLink 使用TABLEscheduleId 生成序列。 这似乎是默认设置。

您可以使用表在任何数据库上生成标识符。这个 策略完全可以跨数据库移植,将是 启用模式生成时自动为您生成

根据EclipseLink 文档,您可能必须对scheduleId 使用IDENTITY 的生成策略以避免TABLE 方法。

@GeneratedValue(strategy=GenerationType.IDENTITY)

请注意,如果您使用如下所示的AUTO 策略,那么即使在这种情况下,EclipseLink 也可能会选择TABLE 策略来生成 ID。

@GeneratedValue(strategy=GenerationType.AUTO)

使用默认生成策略

指定 AUTO 策略 允许 EclipseLink 选择要使用的策略。通常, EclipseLink 选择 TABLE 作为策略,因为它是最便携的 战略。但是,当指定 AUTO 时,模式生成必须是 至少使用一次,以便在 数据库。

更多详情请访问PrimaryKeyGeneratedValue 文档

【讨论】:

  • 你能建议一个不使用 scheduleId 的答案吗?
  • 您使用的是什么数据库?您是否为 eclipselink.target-database 指定了一个值?
  • 我正在使用 MySQL,不,我不使用 target-database
  • WandMaker 的答案看起来不错。 rz3r0 你试过这样设置 eclipselink.ddl-generation 属性吗?也许它没有替换已经存在的表,使用 drop-and-create-tables 策略,更多详细信息请参阅eclipse.org/eclipselink/documentation/2.4/jpa/extensions/…
  • 还可以尝试使用 来确保表对 MySQL 友好。不幸的是,我没有准备好测试你的场景,因为我没有在我的项目中使用 EclipseLink。
猜你喜欢
  • 2015-05-08
  • 2016-01-02
  • 2011-08-15
  • 1970-01-01
  • 1970-01-01
  • 2015-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多