当前位置: 首页 > 面试题库 >

多对多单向映射中的持久化枚举集

韩峰
2023-03-14
问题内容

我使用带有注释的Hibernate
3.5.2-FINAL来指定我的持久性映射。我正在努力对应用程序和一组平台之间的关系进行建模。每个应用程序都可用于一组平台。

从我完成的所有阅读和搜索中,我认为我需要让平台枚举类作为Entity持久化,并需要一个联接表来表示多对多关系。我希望该关系在对象级别是单向的,也就是说,我希望能够获得给定应用程序的平台列表,但是我不需要找出给定平台的应用程序列表。

这是我的简化模型类:

@Entity
@Table(name = "TBL_PLATFORM")
public enum Platform {
    Windows,
    Mac,
    Linux,
    Other;

    @Id
    @GeneratedValue
    @Column(name = "ID")
    private Long id = null;

    @Column(name = "NAME")
    private String name;

    private DevicePlatform() {
        this.name = toString();
    }

    // Setters and getters for id and name...
}

@Entity
@Table(name = "TBL_APP")
public class Application extends AbstractEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name = "NAME")
    protected String _name;

    @ManyToMany(cascade = javax.persistence.CascadeType.ALL)
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
    @JoinTable(name = "TBL_APP_PLATFORM", 
              joinColumns = @JoinColumn(name = "APP_ID"),
              inverseJoinColumns = @JoinColumn(name = "PLATFORM_ID"))
    @ElementCollection(targetClass=Platform.class)
    protected Set<Platform> _platforms;

    // Setters and getters...
}

当我运行Hibernate hbm2ddl工具时,看到以下内容(我正在使用MySQL):

create table TBL_APP_PLATFORM (
    APP_ID bigint not null,
    PLATFORM_ID bigint not null,
    primary key (APP_ID, PLATFORM_ID)
);

还将从此表到应用程序表和平台表创建适当的外键。到目前为止,一切都很好。

我遇到的一个问题是当我尝试保留应用程序对象时:

Application newApp = new Application();
newApp.setName("The Test Application");
Set<DevicePlatform> platforms = EnumSet.of(Platform.Windows, Platform.Linux);
newApp.setPlatforms(platforms);
applicationDao.addApplication(newApp);

我想做的是在Platform表中创建适当的行,即为Windows和Linux创建一个行(如果它们不存在的话)。然后,应为新应用程序创建一行,然后在新应用程序与联接表中的两个平台之间创建映射。

我遇到的一个问题是遇到以下运行时异常:

2010-06-30 13:18:09,382 6613126-0 ERROR FlushingEventListener Could not synchronize database state with session org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.example.model.Platform

以某种方式,当我尝试持久化应用程序时,平台集并没有被持久化。级联注释应该可以解决这个问题,但是我不知道这是怎么回事。

所以我的问题是:

  1. 有没有更好的方法来建模我想做的事情,例如使用枚举是否合适?
  2. 如果我的模型没问题,如何正确持久化所有对象?

我已经为此苦苦挣扎了几个小时,并且尝试重新创建上面的所有代码,但是它可能并不完整和/或准确。我希望有人指出一些明显的东西!


问题答案:

您应该确定您Platform是否为 实体

如果是实体,则不能是enum,因为可能平台的列表存储在数据库中,而不是应用程序中。它应该是带有@Entity注释的常规类,并且您将具有正常的多对多关系。

如果不是实体,则不需要TBL_PLATFORM表,也就没有多对多关系。在这种情况下,您可以将Platforms
的集合表示为带有位标志的整数字段,或者表示为简单的一对多关系。JPA 2.0使用@ElementCollection以下命令简化了后一种情况:

@ElementCollection(targetClass = Platform.class) 
@CollectionTable(name = "TBL_APP_PLATFORM",
    joinColumns = @JoinColumn(name = "APP_ID"))
@Column(name = "PLATFORM_ID")
protected Set<Platform> _platforms;

--

create table TBL_APP_PLATFORM (   
    APP_ID bigint not null,   
    PLATFORM_ID bigint not null, -- the ordinal number of enum value   
    primary key (APP_ID, PLATFORM_ID)   
);

并且enum Platform没有注释。



 类似资料:
  • persistenceException:DB2 SQL错误:sqlcode=-206,sqlstate=42703,sqlerrmc=t0.id,driver=3.52.95{prepstmnt 1029586270

  • 谢谢 ----更新----

  • 问题内容: 在我的MySQL数据库中,有“ gender enum(’male’,’female’)”列 我创建了枚举“ com.mydomain.myapp.enums.Gender”,并在我的实体中定义了“性别”。 现在,我想将枚举类型保留在我的MySQL数据库中,但是当我启动应用程序时,我得到: 性别列在MyApp.Person中的列类型错误。找到:枚举,预期:整数 为什么是这样?这就像我用

  • 问题内容: 在我的MySQL数据库中,有“ gender enum(’male’,’female’)”列 我创建了枚举“ com.mydomain.myapp.enums.Gender”,并在我的实体中定义了“性别”。 现在,我想将枚举类型保留在我的MySQL数据库中,但是当我启动应用程序时,我得到: 性别列在MyApp.Person中的列类型错误。找到:枚举,预期:整数 为什么是这样?就像我用“

  • 问题内容: 我想在打字稿中使用字符串枚举,但在其中看不到对反向映射的支持。我有一个这样的枚举: 我需要这样使用它: 是的,我不知道字符串中有什么,如果字符串未在枚举定义中显示,我需要将其解析为枚举或在运行时解析失败。我该如何做到整洁呢?提前致谢 问题答案: 我们可以将其设为一个类型,并将值设为同一类型。 更严格的版本: 字符串枚举作为此答案:

  • 但是,我有两个实体:角色和用户,它们具有多对多的关系,这由rolesusers表表示。在我的应用程序中,我使用的是JSF2.0,我有一个表单来操作用户数据,还有一个表单,它包含所有角色名称的列表和一个selectBooleanCheckbox来查看用户的角色(如果是,则选中)。此外,它必须有添加或删除rol的可能性(选中或取消选中selectBooleanCheckbox),但当我这样做时,我有两