在多对多单向映射中持久化枚举集
我正在使用Hibernate 3.5.2-FINAL和注释来指定我的持久性映射。我正在努力建模应用程序和一组平台之间的关系。每个应用程序都可用于一组平台。
从我所做的所有阅读和搜索中,我认为我需要将平台枚举类作为实体持久化,并有一个联接表来表示多对多关系。我希望这种关系在对象级别是单向的,也就是说,我希望能够获取给定应用程序的平台列表,但我不需要找出给定平台的应用程序列表。
以下是我的简化模型类:
@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
不知何故,当我尝试持久化应用程序时,平台集没有被持久化。级联注释应该处理这个问题,但我不知道出了什么问题。
所以我的问题是:
- 有没有更好的方法来模拟我想做的事情,例如,使用枚举是否合适?
- 如果我的模型正常,如何正确保留所有对象?
我已经为此苦苦挣扎了几个小时,我试图重新创建上面的所有代码,但它可能不完整和/或不准确。我希望有人能指出一些显而易见的事情!