Manejo de ORM, me atrevería a decir "SUPER (PSEUDO-)RELACIONAL", ¿qué tan *cool* puede ser este enfoque?

Bueno, el día de hoy haciendo mis labores diarias, me han pedido darle un vistazo a un trozo de código que estaba haciendo un colega, el cual tiene bastante experiencia en esto de la programación. Sin embargo, pues vi algo extraño en su código (completamente comprensible, dada su experiencia con ORM, aunque su enfoque me pareció algo curioso que no sé qué tan bueno o malo pueda ser).

Generalmente usando Hibernate o cualquier otro ORM parecido tenemos código más o menos así:

package models;

//Supongamos que la clase Model, es un
//yuyo mágico que nos hemos creado para
//cosas base cómo las bajas altas y cambios.
@Entity
class Alumno extends Model{

----private String
-------nombre,
-------apellido;

----private int semestresCursados;

//Atención a esto
---private Set<Materia> materias;

//Pleyade de getters, setters y más cosas
}

//Luego tenemos otra clase
@Entity
class Materia extends Model{

----private String
------nombre,
------descripcion;

----private int creditos;

----private Set<Materias> dependeDe;

//De nuevo pleyade de getters y setters.
}

Esto parece bastante normal, claro que me faltan las anotaciones de relación (@OneToMany -un objeto cómo este tiene uno o varios cómo el que quiero referir-, @ManyToMany -muchos objetos cómo este tienen uno o varios cómo a los que quiero referir, mismos que pueden referir a varios cómo este-, @ManyToOne -muchos objetos cómo este pertenecen a un objeto cómo el que quiero referir-). Y, a las propiedades 'de relación' habrá que agregarles estrategias de carga (conocido cómo 'fetch mode', generalmente usando LAZY o EAGER), que son también otra anotación.

Ahora, el código que vi esta mañana propone algo parecido a:

package models;

//Supongamos que la clase Model, es un
//yuyo mágico que nos hemos creado para
//cosas base cómo las bajas altas y cambios.
@Entity
class Alumno extends Model{

----private String
-------nombre,
-------apellido;

----private int semestresCursados;

//Pleyade de getters, setters y más cosas
}

//Luego tenemos otra clase
@Entity
class Materia extends Model{

----private String
------nombre,
------descripcion;

----private int creditos;

//De nuevo pleyade de getters y setters.
}

@Entity
class AlumnoMateria extends Model{

----private int
------materia_id,
------alumno_id;
}

Me pongo a pensar y en parte, esto nos "ayuda" de alguna manera, pero nos perjudica de una. ¿Ustedes qué opinan?

Yo lo veo con sus ventajas y desventajas cómo todo, incluso me gustaría hacer un experimento.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de luxspes

Intervalos Alumno Materia

Digamos que mas tarde te piden saber a partir de que fecha y hasta que fecha un alumno estuvo en una materia.

Lo correcto es:

@Entity
class AlumnoMateria extends Model{
        private int materia_id, alumno_id;

        private Date fechainicio
        private Date fechafin
}

El @ManyToMany no te permite hacer eso.

Re: Intervalos Alumno Materia

mmm...muy buena puedes escalar un poco más, incluso podría ponerse una lista , arreglo o set de mapas en caso de que haya recursado la materia, con una llave llamada fechaInicio y otra fechaFin...se podrían incluir las veces de recurso. Cuando lo vi me pareció algo extraño pero ya ahora que mencionas esa cosa que se ve simple y que con @ManyToMany no se podría.

Ahora mi pregunta para ti @luxspes que tienes muchísima más experiencia que yo, ¿es normal ver esto cuando se usa un ORM?, porqué si que lo había visto usando consultas planas (sea jdbc o el conector para c#). Pero esto no lo había visto con un ORM.

Imagen de luxspes

el mundo es complicado

mmm...muy buena puedes escalar un poco más, incluso podría ponerse una lista , arreglo o set de mapas en caso de que haya recursado la materia, con una llave llamada fechaInicio y otra fechaFin... se podrían incluir las veces de recurso.

No estoy seguro de a que te refieres... y si lo pones en codigo?

Cuando lo vi me pareció algo extraño pero ya ahora que mencionas esa cosa que se ve simple y que con @ManyToMany no se podría.

Sip, @ManyToMany solo sirve para relaciones Many-to-Many "puras" en las que la tabla intermedia no tiene otro campo que no sean las llaves de las 2 tablas conectadas

Ahora mi pregunta para ti @luxspes que tienes muchísima más experiencia que yo, ¿es normal ver esto cuando se usa un ORM?, porqué si que lo había visto usando consultas planas (sea jdbc o el conector para c#). Pero esto no lo había visto con un ORM.

Pues... no se si normal, pero lo que a mi me a tocado ver es que conforme un sistema evoluciona y se va volviendo mas sofisticado, las relaciones Many-to-Many "puras" desparecen poco a poco... en este caso por ejemplo, para un sistema basico de control escolar, uno puede manejarlo con una relacion Many-to-Many "pura", pero conforme vas avanzando, te das cuenta de que la relacion entre el Alumno y la Materia es mediada por el Tiempo, y el Tiempo (fecha inicio, fecha fin) es generalmente el primero en asesinar a las relaciones Many-to-Many "puras". Despues llegan las consideraciones de seguridad "quien fue la persona que asocio esa materia con ese alumno", y luego llegan los otros datos, como por ejemplo, las calificaciones el alumno en la materia, etc, etc, y con un sistema robusto y rico en funcionalidad, generalmente terminas con algo asi:

@Entity
class AlumnoMateria extends Model{
        private int materia_id, alumno_id;

        private Date fechainicio
        private Date fechafin

        private BigDecimal calificacion;
        private Usuario usuarioQueRegistro;
}

Digamos que se puede resumir en "el mundo es complicado" y las relaciones Many-to-many "puras" rara vez tienen lugar en el.

Re: el mundo es complicado

No estoy seguro de a que te refieres... y si lo pones en codigo?

@Entity
class AlumnoMateria extends Model{
----private int
------materia_id,
------alumno_id;

----private List<Map<String, Date>> cursosLlevados; //Y aquí podríamos agregar en que periodo(s) cursó.
}

Es interesante plantearse esos escenarios que pocas personas al enseñar lo toman en cuenta y por lo general se ven muchos ejemplos con relaciones no sólo @ManyToMany, incluso muchas veces existen problemas con los ORM cómo las referencias circulares (que por ejemplo impiden el uso de librerías cómo GSON, para convertir un objeto Java a un JSON).

Gracias por el ampliado de panorama :D