JPA - Asignaciones avanzadas

JPA es una biblioteca que se publica con la especificación java. Por lo tanto, admite todos los conceptos orientados a objetos para la persistencia de entidades. Hasta ahora hemos terminado con los conceptos básicos del mapeo relacional de objetos. Este capítulo lo lleva a través de las asignaciones avanzadas entre objetos y entidades relacionales.

Estrategias de herencia

La herencia es el concepto central del lenguaje orientado a objetos, por lo que podemos utilizar relaciones o estrategias de herencia entre entidades. JPA admite tres tipos de estrategias de herencia, como SINGLE_TABLE, JOINED_TABLE y TABLE_PER_CONCRETE_CLASS.

Consideremos un ejemplo de las clases Staff, TeachingStaff, Non TeachingStaff y sus relaciones de la siguiente manera:

En el diagrama que se muestra arriba, Staff es una entidad y TeachingStaff y NonTeachingStaff son las subentidades de Staff. Aquí discutiremos el ejemplo anterior en las tres estrategias de herencia.

Estrategia de mesa única

La estrategia de tabla única toma todos los campos de clases (tanto superclases como subclases) y los mapea en una sola tabla conocida como estrategia SINGLE_TABLE. Aquí, el valor discriminador juega un papel clave en la diferenciación de los valores de tres entidades en una tabla.

Consideremos el ejemplo anterior, TeachingStaff y NonTeachingStaff son las subclases de la clase Staff. Recuerde el concepto de herencia (es un mecanismo de heredar las propiedades de superclase por subclase) y por lo tanto sid, sname son los campos que pertenecen tanto a TeachingStaff como a NonTeachingStaff. Crea un proyecto JPA. Todos los módulos de este proyecto de la siguiente manera:

Creando Entidades

Crea un paquete llamado ‘com.tutorialspoint.eclipselink.entity’ debajo ‘src’paquete. Crea una nueva clase java llamadaStaff.javabajo paquete dado. La clase de entidad Staff se muestra a continuación:

package com.tutorialspoint.eclipselink.entity;

import java.io.Serializable;

import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

@Entity
@Table
@Inheritance( strategy = InheritanceType.SINGLE_TABLE )
@DiscriminatorColumn( name = "type" )

public class Staff implements Serializable {
   @Id
   @GeneratedValue( strategy = GenerationType.AUTO )
   
   private int sid;
   private String sname;
   
   public Staff( int sid, String sname ) {
      super( );
      this.sid = sid;
      this.sname = sname;
   }
   
   public Staff( ) {
      super( );
   }
   
   public int getSid( ) {
      return sid;
   }
   
   public void setSid( int sid ) {
      this.sid = sid;
   }
   
   public String getSname( ) {
      return sname;
   }
   
   public void setSname( String sname ) {
      this.sname = sname;
   }
}

En el código anterior @DescriminatorColumn especifica el nombre del campo (type) y sus valores muestran los campos restantes (personal docente y no docente).

Cree una subclase (clase) para la clase de personal llamada TeachingStaff.java bajo la com.tutorialspoint.eclipselink.entitypaquete. La clase de entidad TeachingStaff se muestra a continuación:

package com.tutorialspoint.eclipselink.entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue( value="TS" )
public class TeachingStaff extends Staff {

   private String qualification;
   private String subjectexpertise;

   public TeachingStaff( int sid, String sname, 
   
   String qualification,String subjectexpertise ) {
      super( sid, sname );
      this.qualification = qualification;
      this.subjectexpertise = subjectexpertise;
   }

   public TeachingStaff( ) {
      super( );
   }

   public String getQualification( ){
      return qualification;
   }

   public void setQualification( String qualification ){
      this.qualification = qualification;
   }

   public String getSubjectexpertise( ) {
      return subjectexpertise;
   }

   public void setSubjectexpertise( String subjectexpertise ){
      this.subjectexpertise = subjectexpertise;
   }
}

Cree una subclase (clase) para la clase de personal llamada NonTeachingStaff.java bajo la com.tutorialspoint.eclipselink.entitypaquete. La clase de entidad NonTeachingStaff se muestra a continuación:

package com.tutorialspoint.eclipselink.entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue( value = "NS" )

public class NonTeachingStaff extends Staff {
   private String areaexpertise;

   public NonTeachingStaff( int sid, String sname, String areaexpertise ) {
      super( sid, sname );
      this.areaexpertise = areaexpertise;
   }

   public NonTeachingStaff( ) {
      super( );
   }

   public String getAreaexpertise( ) {
      return areaexpertise;
   }

   public void setAreaexpertise( String areaexpertise ){
      this.areaexpertise = areaexpertise;
   }
}

Persistence.xml

El archivo Persistence.xml contiene la información de configuración de la base de datos y la información de registro de las clases de entidad. El archivo xml se muestra a continuación:

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
   http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

   <persistence-unit name="Eclipselink_JPA" transaction-type="RESOURCE_LOCAL">
   
      <class>com.tutorialspoint.eclipselink.entity.Staff</class>
      <class>com.tutorialspoint.eclipselink.entity.NonTeachingStaff</class>
      <class>com.tutorialspoint.eclipselink.entity.TeachingStaff</class>
      
      <properties>
         <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpadb"/>
         <property name="javax.persistence.jdbc.user" value="root"/>
         <property name="javax.persistence.jdbc.password" value="root"/>
         <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
         <property name="eclipselink.logging.level" value="FINE"/>
         <property name="eclipselink.ddl-generation" value="create-tables"/>
      </properties>
      
   </persistence-unit>
</persistence>

Clase de servicio

Las clases de servicio son la parte de implementación del componente empresarial. Crea un paquete debajo‘src’ paquete llamado ‘com.tutorialspoint.eclipselink.service’.

Cree una clase llamada SaveClient.java en el paquete dado para almacenar los campos de clase Staff, TeachingStaff y NonTeachingStaff. La clase SaveClient se muestra a continuación:

package com.tutorialspoint.eclipselink.service;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.tutorialspoint.eclipselink.entity.NonTeachingStaff;
import com.tutorialspoint.eclipselink.entity.TeachingStaff;

public class SaveClient {

   public static void main( String[ ] args ) {
   
      EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
      EntityManager entitymanager = emfactory.createEntityManager( );
      entitymanager.getTransaction( ).begin( );

      //Teaching staff entity 
      TeachingStaff ts1=new TeachingStaff(1,"Gopal","MSc MEd","Maths");
      TeachingStaff ts2=new TeachingStaff(2, "Manisha", "BSc BEd", "English");
      
      //Non-Teaching Staff entity
      NonTeachingStaff nts1=new NonTeachingStaff(3, "Satish", "Accounts");
      NonTeachingStaff nts2=new NonTeachingStaff(4, "Krishna", "Office Admin");

      //storing all entities
      entitymanager.persist(ts1);
      entitymanager.persist(ts2);
      entitymanager.persist(nts1);
      entitymanager.persist(nts2);
      
      entitymanager.getTransaction().commit();
      
      entitymanager.close();
      emfactory.close();
   }
}

Después de la compilación y ejecución del programa anterior, recibirá notificaciones en el panel de la consola de Eclipse IDE. Consulte la salida de MySQL workbench. La salida en formato tabular se muestra a continuación:

Sid Tipo Nombre de Área de experiencia Calificación Subjectexpertise
1 TS Gopal MSC MED Matemáticas
2 TS Manisha CAMA BSC Inglés
3 NS Satish Cuentas
4 NS Krishna Administrador de oficina

Finalmente obtendrá una tabla única que contiene los campos de las tres clases y difiere con la columna discriminadora llamada ‘Type’ (campo).

Estrategia de mesa unida

La estrategia de la tabla unida es compartir la columna referenciada que contiene valores únicos para unirse a la tabla y hacer transacciones fáciles. Consideremos el mismo ejemplo anterior.

Cree un proyecto JPA. Todos los módulos del proyecto se muestran a continuación:

Creando Entidades

Crea un paquete llamado ‘com.tutorialspoint.eclipselink.entity’ debajo ‘src’paquete. Crea una nueva clase java llamadaStaff.javabajo paquete dado. La clase de entidad Staff se muestra a continuación:

package com.tutorialspoint.eclipselink.entity;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

@Entity
@Table
@Inheritance( strategy = InheritanceType.JOINED )

public class Staff implements Serializable {

   @Id
   @GeneratedValue( strategy = GenerationType.AUTO )
   
   private int sid;
   private String sname;
   
   public Staff( int sid, String sname ) {
      super( );
      this.sid = sid;
      this.sname = sname;
   }
   
   public Staff( ) {
      super( );
   }
   
   public int getSid( ) {
      return sid;
   }
   
   public void setSid( int sid ) {
      this.sid = sid;
   }
   
   public String getSname( ) {
      return sname;
   }
   
   public void setSname( String sname ) {
      this.sname = sname;
   }
}

Cree una subclase (clase) para la clase de personal llamada TeachingStaff.java bajo la com.tutorialspoint.eclipselink.entitypaquete. La clase de entidad TeachingStaff se muestra a continuación:

package com.tutorialspoint.eclipselink.entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@PrimaryKeyJoinColumn(referencedColumnName="sid")

public class TeachingStaff extends Staff {
   private String qualification;
   private String subjectexpertise;

   public TeachingStaff( int sid, String sname, 
   
   String qualification,String subjectexpertise ) {
      super( sid, sname );
      this.qualification = qualification;
      this.subjectexpertise = subjectexpertise;
   }

   public TeachingStaff( ) {
      super( );
   }

   public String getQualification( ){
      return qualification;
   }

   public void setQualification( String qualification ){
      this.qualification = qualification;
   }

   public String getSubjectexpertise( ) {
      return subjectexpertise;
   }

   public void setSubjectexpertise( String subjectexpertise ){
      this.subjectexpertise = subjectexpertise;
   }
}

Cree una subclase (clase) para la clase de personal llamada NonTeachingStaff.java bajo la com.tutorialspoint.eclipselink.entitypaquete. La clase de entidad NonTeachingStaff se muestra a continuación:

package com.tutorialspoint.eclipselink.entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@PrimaryKeyJoinColumn(referencedColumnName="sid")

public class NonTeachingStaff extends Staff {
   private String areaexpertise;

   public NonTeachingStaff( int sid, String sname, String areaexpertise ) {
      super( sid, sname );
      this.areaexpertise = areaexpertise;
   }

   public NonTeachingStaff( ) {
      super( );
   }

   public String getAreaexpertise( ) {
      return areaexpertise;
   }

   public void setAreaexpertise( String areaexpertise ) {
      this.areaexpertise = areaexpertise;
   }
}

Persistence.xml

El archivo Persistence.xml contiene la información de configuración de la base de datos y la información de registro de las clases de entidad. El archivo xml se muestra a continuación:

<?xml version = "1.0" encoding = "UTF-8"?>

<persistence version = "2.0" xmlns = "http://java.sun.com/xml/ns/persistence" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation = "http://java.sun.com/xml/ns/persistence 
   http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   
   <persistence-unit name = "Eclipselink_JPA" transaction-type = "RESOURCE_LOCAL">
      <class>com.tutorialspoint.eclipselink.entity.Staff</class>
      <class>com.tutorialspoint.eclipselink.entity.NonTeachingStaff</class>
      <class>com.tutorialspoint.eclipselink.entity.TeachingStaff</class>
      
      <properties>
         <property name = "javax.persistence.jdbc.url" value = "jdbc:mysql://localhost:3306/jpadb"/>
         <property name = "javax.persistence.jdbc.user" value = "root"/>
         <property name = "javax.persistence.jdbc.password" value = "root"/>
         <property name = "javax.persistence.jdbc.driver" value = "com.mysql.jdbc.Driver"/>
         <property name = "eclipselink.logging.level" value = "FINE"/>
         <property name = "eclipselink.ddl-generation" value = "create-tables"/>
      </properties>
      
   </persistence-unit>
</persistence>

Clase de servicio

Las clases de servicio son la parte de implementación del componente empresarial. Crea un paquete debajo‘src’ paquete llamado ‘com.tutorialspoint.eclipselink.service’.

Cree una clase llamada SaveClient.java en el paquete dado para almacenar los campos de clase Staff, TeachingStaff y NonTeachingStaff. Luego, la clase SaveClient de la siguiente manera:

package com.tutorialspoint.eclipselink.service;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.tutorialspoint.eclipselink.entity.NonTeachingStaff;
import com.tutorialspoint.eclipselink.entity.TeachingStaff;

public class SaveClient {
   public static void main( String[ ] args ) {
      EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
      EntityManager entitymanager = emfactory.createEntityManager( );
      entitymanager.getTransaction( ).begin( );

      //Teaching staff entity 
      TeachingStaff ts1 = new TeachingStaff(1,"Gopal","MSc MEd","Maths");
      TeachingStaff ts2 = new TeachingStaff(2, "Manisha", "BSc BEd", "English");
      
      //Non-Teaching Staff entity
      NonTeachingStaff nts1 = new NonTeachingStaff(3, "Satish", "Accounts");
      NonTeachingStaff nts2 = new NonTeachingStaff(4, "Krishna", "Office Admin");

      //storing all entities
      entitymanager.persist(ts1);
      entitymanager.persist(ts2);
      entitymanager.persist(nts1);
      entitymanager.persist(nts2);

      entitymanager.getTransaction().commit();
      entitymanager.close();
      emfactory.close();
   }
}

Después de la compilación y ejecución del programa anterior, recibirá notificaciones en el panel de la consola de Eclipse IDE. Para la salida, verifique el banco de trabajo MySQL de la siguiente manera:

Aquí se crean tres tablas y el resultado de staff La tabla en formato tabular se muestra a continuación:

Sid Dtype Nombre de
1 Personal docente Gopal
2 Personal docente Manisha
3 No DocentePersonal Satish
4 No DocentePersonal Krishna

El resultado de TeachingStaff La tabla en formato tabular se muestra a continuación:

Sid Calificación Subjectexpertise
1 MSC MED Matemáticas
2 CAMA BSC Inglés

En la tabla anterior, sid es la clave externa (campo de referencia del formulario de tabla de personal) El resultado de NonTeachingStaff La tabla en formato tabular se muestra a continuación:

Sid Área de experiencia
3 Cuentas
4 Administrador de oficina

Finalmente, las tres tablas se crean utilizando sus campos respectivamente y el campo SID es compartido por las tres tablas. En la tabla de personal, SID es la clave principal, en las tablas restantes (TeachingStaff y NonTeachingStaff), SID es una clave externa.

Tabla por estrategia de clase

La estrategia de tabla por clase es crear una tabla para cada subentidad. Se creará la tabla de personal pero contendrá registros nulos. Los valores de campo de la tabla Staff deben ser compartidos por las tablas TeachingStaff y NonTeachingStaff.

Consideremos el mismo ejemplo anterior. Todos los módulos de este proyecto se muestran a continuación:

Creando Entidades

Crea un paquete llamado ‘com.tutorialspoint.eclipselink.entity’ debajo ‘src’paquete. Crea una nueva clase java llamadaStaff.javabajo paquete dado. La clase de entidad Staff se muestra a continuación:

package com.tutorialspoint.eclipselink.entity;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

@Entity
@Table
@Inheritance( strategy = InheritanceType.TABLE_PER_CLASS )

public class Staff implements Serializable {

   @Id
   @GeneratedValue( strategy = GenerationType.AUTO )

   private int sid;
   private String sname;

   public Staff( int sid, String sname ) {
      super( );
      this.sid = sid;
      this.sname = sname;
   }

   public Staff( ) {
      super( );
   }

   public int getSid( ) {
      return sid;
   }

   public void setSid( int sid ) {
      this.sid = sid;
   }

   public String getSname( ) {
      return sname;
   }

   public void setSname( String sname ) {
      this.sname = sname;
   }
}

Cree una subclase (clase) para la clase de personal llamada TeachingStaff.java bajo la com.tutorialspoint.eclipselink.entitypaquete. La clase de entidad TeachingStaff se muestra a continuación:

package com.tutorialspoint.eclipselink.entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
public class TeachingStaff extends Staff {
   private String qualification;
   private String subjectexpertise;

   public TeachingStaff( int sid, String sname, String qualification, String subjectexpertise ) {
      super( sid, sname );
      this.qualification = qualification;
      this.subjectexpertise = subjectexpertise;
   }

   public TeachingStaff( ) {
      super( );
   }

   public String getQualification( ){
      return qualification;
   }
   
   public void setQualification( String qualification ) {
      this.qualification = qualification;
   }

   public String getSubjectexpertise( ) {
      return subjectexpertise;
   }

   public void setSubjectexpertise( String subjectexpertise ){
      this.subjectexpertise = subjectexpertise;
   }
}

Cree una subclase (clase) para la clase de personal llamada NonTeachingStaff.java bajo la com.tutorialspoint.eclipselink.entitypaquete. La clase de entidad NonTeachingStaff se muestra a continuación:

package com.tutorialspoint.eclipselink.entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
public class NonTeachingStaff extends Staff {
   private String areaexpertise;

   public NonTeachingStaff( int sid, String sname, String areaexpertise ) {
      super( sid, sname );
      this.areaexpertise = areaexpertise;
   }

   public NonTeachingStaff( ) {
      super( );
   }

   public String getAreaexpertise( ) {
      return areaexpertise;
   }

   public void setAreaexpertise( String areaexpertise ) {
      this.areaexpertise = areaexpertise;
   }
}

Persistence.xml

El archivo Persistence.xml contiene la información de configuración de la base de datos y la información de registro de las clases de entidad. El archivo xml se muestra a continuación:

<?xml version="1.0" encoding = "UTF-8"?>
<persistence version = "2.0" xmlns = "http://java.sun.com/xml/ns/persistence"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation = "http://java.sun.com/xml/ns/persistence 
   http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

   <persistence-unit name = "Eclipselink_JPA" transaction-type = "RESOURCE_LOCAL">
      <class>com.tutorialspoint.eclipselink.entity.Staff</class>
      <class>com.tutorialspoint.eclipselink.entity.NonTeachingStaff</class>
      <class>com.tutorialspoint.eclipselink.entity.TeachingStaff</class>
      
      <properties>
         <property name = "javax.persistence.jdbc.url" value = "jdbc:mysql://localhost:3306/jpadb"/>
         <property name = "javax.persistence.jdbc.user" value = "root"/>
         <property name = "javax.persistence.jdbc.password" value = "root"/>
         <property name = "javax.persistence.jdbc.driver" value = "com.mysql.jdbc.Driver"/>
         <property name = "eclipselink.logging.level" value = "FINE"/>
         <property name = "eclipselink.ddl-generation" value="create-tables"/>
      </properties>
      
   </persistence-unit>
</persistence>

Clase de servicio

Las clases de servicio son la parte de implementación del componente empresarial. Crea un paquete debajo‘src’ paquete llamado ‘com.tutorialspoint.eclipselink.service’.

Crea una clase llamada SaveClient.javaen el paquete proporcionado para almacenar los campos de clase Staff, TeachingStaff y NonTeachingStaff. La clase SaveClient se muestra a continuación:

package com.tutorialspoint.eclipselink.service;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.tutorialspoint.eclipselink.entity.NonTeachingStaff;
import com.tutorialspoint.eclipselink.entity.TeachingStaff;

public class SaveClient {
   public static void main( String[ ] args ) {
      EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
      EntityManager entitymanager = emfactory.createEntityManager( );
      entitymanager.getTransaction( ).begin( );

      //Teaching staff entity 
      TeachingStaff ts1 = new TeachingStaff(1,"Gopal","MSc MEd","Maths");
      TeachingStaff ts2 = new TeachingStaff(2, "Manisha", "BSc BEd", "English");
      
      //Non-Teaching Staff entity
      NonTeachingStaff nts1 = new NonTeachingStaff(3, "Satish", "Accounts");
      NonTeachingStaff nts2 = new NonTeachingStaff(4, "Krishna", "Office Admin");

      //storing all entities
      entitymanager.persist(ts1);
      entitymanager.persist(ts2);
      entitymanager.persist(nts1);
      entitymanager.persist(nts2);

      entitymanager.getTransaction().commit();
      entitymanager.close();
      emfactory.close();
   }
}

Después de la compilación y ejecución del programa anterior, recibirá notificaciones en el panel de la consola de Eclipse IDE. Para obtener resultados, consulte MySQL workbench de la siguiente manera:

Aquí se crean las tres tablas y Staff La tabla contiene registros nulos.

El resultado de TeachingStaff en formato tabular se muestra a continuación:

Sid Calificación Nombre de Subjectexpertise
1 MSC MED Gopal Matemáticas
2 CAMA BSC Manisha Inglés

La tabla anterior TeachingStaff contiene campos de Entidades Staff y TeachingStaff.

El resultado de NonTeachingStaff en formato tabular se muestra a continuación:

Sid Área de experiencia Nombre de
3 Cuentas Satish
4 Administrador de oficina Krishna

La tabla anterior NonTeachingStaff contiene campos de Entidades Staff y NonTeachingStaff.