Java 在多对多单向映射中持久化枚举集
我正在使用Hibernate 3.5.2-FINAL和注释来指定我的持久性映射。我正在努力为应用程序和一组平台之间的关系建模。每个应用程序都可用于一组平台 从我所做的所有阅读和搜索中,我认为我需要将平台枚举类作为一个实体进行持久化,并需要一个连接表来表示多对多关系。我希望关系在对象级别是单向的,也就是说,我希望能够获得给定应用程序的平台列表,但我不需要找到给定平台的应用程序列表 以下是我的简化模型类:Java 在多对多单向映射中持久化枚举集,java,hibernate,jpa,persistence,annotations,Java,Hibernate,Jpa,Persistence,Annotations,我正在使用Hibernate 3.5.2-FINAL和注释来指定我的持久性映射。我正在努力为应用程序和一组平台之间的关系建模。每个应用程序都可用于一组平台 从我所做的所有阅读和搜索中,我认为我需要将平台枚举类作为一个实体进行持久化,并需要一个连接表来表示多对多关系。我希望关系在对象级别是单向的,也就是说,我希望能够获得给定应用程序的平台列表,但我不需要找到给定平台的应用程序列表 以下是我的简化模型类: @Entity @Table(name = "TBL_PLATFORM") public en
@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...
}
相应的外键也将从此表创建到应用程序表和平台表。到目前为止还不错
我遇到的一个问题是,当我尝试持久化应用程序对象时:
Application newApp = new Application();
newApp.setName("The Test Application");
Set<DevicePlatform> platforms = EnumSet.of(Platform.Windows, Platform.Linux);
newApp.setPlatforms(platforms);
applicationDao.addApplication(newApp);
不知何故,当我尝试持久化应用程序时,平台集没有被持久化。级联注释应该会解决这个问题,但我不知道出了什么问题
因此,我的问题是:
我已经为此挣扎了几个小时,我尝试重新创建上面的所有代码,但它可能不完整和/或不准确。我希望有人能指出一些显而易见的事情 您应该决定您的
平台
是否为实体
如果它是一个实体,则不能是枚举
,因为可能的平台列表存储在数据库中,而不是应用程序中。它应该是一个带有@Entity
注释的常规类,您将拥有一个正常的多对多关系
如果它不是一个实体,那么您就不需要TBL_PLATFORM
表,也不需要多对多关系。在这种情况下,您可以将一组平台
表示为带位标志的整数字段,或者表示为简单的一对多关系。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;
和
enum Platform
无注释。在实体上使用下面的映射即可。假设我们有:
public enum TestEnum { A, B }
然后在实体类中:
@ElementCollection(targetClass = TestEnum.class)
@CollectionTable(
name = "yourJoinTable",
joinColumns = @JoinColumn(name = "YourEntityId")
)
@Column(name = "EnumId")
private final Set<TestEnum> enumSet= new HashSet<>();
@ElementCollection(targetClass=TestEnum.class)
@收集表(
name=“yourJoinTable”,
joinColumns=@JoinColumn(name=“YourEntityId”)
)
@列(name=“EnumId”)
私有最终集enumSet=新HashSet();
以下示例显示了当模块是实体而语言是枚举时的情况
@Entity
public class Module {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String libelle;
@ElementCollection(targetClass = Langue.class, fetch = FetchType.EAGER)
@CollectionTable(name = "link_module_langue",
joinColumns = @JoinColumn(name = "module_id", referencedColumnName = "id"))
@Enumerated(EnumType.STRING)
@Column(name = "langue")
private Set<Langue> langues;
}
public enum Langue {
FRANCAIS, ANGLAIS, ESPAGNOLE
}
NB:Langue不是一个实体,也不会有自己的表。我使用了Hibernate的旧版本来生成模式。通过以下操作,我将依赖项设置为3.5.3-FINAL,“org.hibernate.MappingException:无法确定:java.util.set的类型”消失了。我遵循了您建议的@ElementCollection方法,使用了一个普通的非实体枚举,现在Set被映射到一个联接表。而且,通过在属性上设置@Enumerated,我可以设置枚举值是作为整数还是字符串存储在数据库中。@axtavt我在那里附加了一个赏金,你能帮我一下吗。。急需帮助。@axtavt能否在帖子中添加原则表“TBL_应用程序”的结构?Thnx
public enum TestEnum { A, B }
@ElementCollection(targetClass = TestEnum.class)
@CollectionTable(
name = "yourJoinTable",
joinColumns = @JoinColumn(name = "YourEntityId")
)
@Column(name = "EnumId")
private final Set<TestEnum> enumSet= new HashSet<>();
@Entity
public class Module {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String libelle;
@ElementCollection(targetClass = Langue.class, fetch = FetchType.EAGER)
@CollectionTable(name = "link_module_langue",
joinColumns = @JoinColumn(name = "module_id", referencedColumnName = "id"))
@Enumerated(EnumType.STRING)
@Column(name = "langue")
private Set<Langue> langues;
}
public enum Langue {
FRANCAIS, ANGLAIS, ESPAGNOLE
}
CREATE TABLE `link_module_langue` (
`module_id` BIGINT(20) NOT NULL,
`langue` VARCHAR(45) NOT NULL,
PRIMARY KEY (`module_id`, `langue`),
CONSTRAINT `module_fk`
FOREIGN KEY (`module_id`)
REFERENCES `module` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE);