Estoy usando Hibernate 3.5.2-FINAL con anotaciones para especificar mis asignaciones de persistencia. Estoy luchando con el modelado de una relación entre una aplicación y un conjunto de plataformas. Cada aplicación está disponible para un conjunto de plataformas.Conjunto persistente de entradas en un mapeo unidireccional de muchos a varios
De toda la lectura y búsqueda que he hecho, creo que necesito que la plataforma enum class se persista como Entity, y tener una tabla join para representar la relación many-to-many. Quiero que la relación sea unidireccional a nivel de objeto, es decir, quiero poder obtener la lista de plataformas para una aplicación determinada, pero no necesito encontrar la lista de aplicaciones para una plataforma determinada.
Éstos son mis clases del modelo simplificado:
@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...
}
Cuando ejecuto la herramienta hbm2ddl Hibernate, veo el siguiente (estoy usando MySQL):
create table TBL_APP_PLATFORM (
APP_ID bigint not null,
PLATFORM_ID bigint not null,
primary key (APP_ID, PLATFORM_ID)
);
Las claves externas son adecuadas también creado a partir de esta tabla para la tabla de la aplicación y la plataforma. Hasta aquí todo bien.
Un problema que estoy corriendo en es cuando trato de persistir un objeto de aplicación:
Application newApp = new Application();
newApp.setName("The Test Application");
Set<DevicePlatform> platforms = EnumSet.of(Platform.Windows, Platform.Linux);
newApp.setPlatforms(platforms);
applicationDao.addApplication(newApp);
Lo que me gustaría que suceda es para las filas apropiadas en la tabla de plataforma para crear, es decir, crear una fila para Windows y Linux, si aún no existen. Luego, se debe crear una fila para la nueva aplicación y luego la asignación entre la nueva aplicación y las dos plataformas en la tabla de unión.
Un problema que estoy corriendo en está recibiendo la siguiente excepción en tiempo de ejecución:
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
De alguna manera, el conjunto de la plataforma no está siendo persistió cuando trato de persistir la aplicación. Se supone que las anotaciones en cascada se encargan de eso, pero no sé qué ocurre.
Así que mis preguntas son:
- ¿Hay una mejor manera de modelar lo que quiero hacer, por ejemplo, está usando un Enum apropiado?
- Si mi modelo está bien, ¿cómo puedo conservar correctamente todos los objetos?
He estado luchando con esto durante horas y he tratado de volver a crear todo el código anterior, pero puede que no sea completo y/o preciso. ¡Espero que alguien señale algo obvio!
que estaba usando una versión anterior de Hibernate para generar el esquema. Al seguir http://stackoverflow.com/questions/2734971/hibernate3-maven-plugin-dependencies-for-newer-version-of-hibernate, establezco una dependencia a 3.5.3-FINAL y "org.hibernate.MappingException: No se pudo determinar el tipo para: java.util.Set "desapareció. Seguí el método @ElementCollection que sugirió, utilizando una enumeración simple sin entidad, y ahora Set se asigna a una tabla de unión. Y, al establecer @Enumerated en la propiedad, puedo establecer si los valores enum se almacenan en la base de datos como enteros o cadenas. –
gnuf
@axtavt ¿me pueden ayudar con http://stackoverflow.com/questions/7687409/hibernate-criteria-query-for-collection-table/7693793#7693793 Adjunté una recompensa allí ... Necesito ayuda ... –
@ axtavt ¿Puedes agregar a tu publicación la estructura de la tabla principal "TBL_APP" por favor? Thnx –