Skip to content

7 Proyecto Students con JPA

Introducción

Una vez conocido todos los conceptos y relaciones pertinentes, es momento de aplicar dichos conocimientos a nuestro proyecto Bookstore, que en la última versión había sido añadida el patrón de diseño Repository. En esta versión, es indiferente el tipo de patrón de diseño a usar, ya que para lo que nos compete el funcionamiento es bastante similar.

Configuración de dependencias

Si usamos un gestor de dependencias como Maven o Gradle, es necesario importar los artifacts, tanto de Hibernate como de JPA, así como el conector de la base de datos:

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
    <dependency>
        <groupId>javax.persistence</groupId>
        <artifactId>javax.persistence-api</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>6.2.7.Final</version>
    </dependency>
</dependencies>
dependencies {
    implementation 'javax.persistence:javax.persistence-api:2.2'
    implementation 'org.hibernate:hibernate-core:5.5.6.Final'
}

Configuración de las ORM

Podemos usar nuestras clases POJOs con anotaciones o haciendo uso del XML:

<entity-mappings xmlns="https://jakarta.ee/xml/ns/persistence/orm"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence/orm https://jakarta.ee/xml/ns/persistence/orm/orm_3_0.xsd"
             version="3.0">
    <entity class="com.irudev.data.entity.Student" >
        <table name="student"/>
        <attributes>
            <id name="id">
                <column name="id"/>
                <generated-value strategy="IDENTITY"/>
            </id>
            <basic name="name">
                <column name="name"/>
            </basic>
            <basic name="age">
                <column name="age"/>
            </basic>
        </attributes>
    </entity>
</entity-mappings>
@Entity
public class Student implements Comparable<Student>{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private int age;

    public Student(){}
    public Student(Integer id, String name, int age){
        this.id = id;
        this.name = name;
        this.age = age;
    }

    // ...
}
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
                                     http://xmlns.jcp.org/xml/ns/persistence/orm_2_2.xsd"
                 version="2.2">
    <entity class="com.irudev.data.entity.Course">
        <table name="course"/>
        <attributes>
            <id name="id">
                <column name="id"/>
                <generated-value strategy="IDENTITY"/>
            </id>
            <basic name="name">
                <column name="name"/>
            </basic>
            <basic name="credits">
                <column name="credits"/>
            </basic>
        </attributes>
    </entity>
</entity-mappings>
@Entity
public class Course implements Comparable<Course>{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private int credits;

    public Course(){}
    // ...
}
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
                                     http://xmlns.jcp.org/xml/ns/persistence/orm_2_2.xsd"
                 version="2.2">
    <entity class="com.irudev.data.entity.Inscription">
        <table name="inscription"/>
        <attributes>
            <id name="id">
                <column name="id"/>
                <generated-value strategy="IDENTITY"/>
            </id>
            <many-to-one name="student" fetch="EAGER">
                <join-column name="idStudent"/>
            </many-to-one>
            <many-to-one name="course" fetch="EAGER">
                <join-column name="idCourse"/>
            </many-to-one>
        </attributes>
    </entity>
</entity-mappings>
@Entity
public class Inscription implements Comparable<Inscription>{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "idStudent")
    private Student student;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "idCourse")
    private Course course;

    public Inscription(){}
    // ...
}

Archivo de configuración

Debemos de crear el archivo de configuración persistence xml

<!-- persistence.xml -->
<persistence version="3.0" xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd">

    <persistence-unit name="myPersistenceUnit">
        <!-- Asignación de Hibernate como JPA Provider -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <!-- Mapeo ORM -->
        <mapping-file>META-INF/orm/Student.xml</mapping-file>
        <mapping-file>META-INF/orm/Course.xml</mapping-file>
        <mapping-file>META-INF/orm/Inscription.xml</mapping-file>


        <!-- Configuración de las propiedades -->
        <properties>
            <!-- Configuración de la fuente de datos para MySQL -->
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/students?useSSL=false&amp;serverTimezone=UTC"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value=""/>

            <!-- Configuración de Hibernate -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

Importante

En el fichero persistence.xml será obligatorio indicar el mapping-file si se usa archivos xml para la ORM en lugar de anotaciones

Modelos

Al no utilizar los métodos ni crear las conexiones, los modelos deben cambiar:

public class JDBCStudentRepository implements StudentRepository {

    private final EntityManager manager;

    public JDBCStudentRepository(EntityManager manager){
        this.manager = manager;
    }

    @Override
    public Student getById(Integer id) {
        return manager.find(Student.class, id);
    }

    @Override
    public List<Student> getAll() {
        return manager.createQuery("select s from Student s", Student.class).getResultList();
    }

    @Override
    public boolean save(Student student) {
        try{
            manager.getTransaction().begin();
            manager.persist(student);
            manager.getTransaction().commit();
            return true;
        }catch (Exception e){
            return false;
        }
    }

    @Override
    public boolean update(Student student) {
        try{
            manager.getTransaction().begin();
            manager.merge(student);
            manager.getTransaction().commit();
            return true;
        }catch (Exception e){
            return false;
        }
    }

    @Override
    public boolean delete(Student student) {
        try{
            manager.getTransaction().begin();
            manager.remove(student);
            manager.getTransaction().commit();
            return true;
        }catch (Exception e){
            return false;
        }
    }
}
public class JDBCCourseRepository implements CourseRepository {
    private final EntityManager manager;

    public JDBCCourseRepository(EntityManager manager) {
        this.manager = manager;
    }

    @Override
    public Course getById(Integer id) {
        return manager.find(Course.class, id);
    }

    @Override
    public List<Course> getAll() {
        return manager.createQuery("select c from Course c", Course.class).getResultList();
    }


    @Override
    public boolean save(Course course) {
        try{
            manager.getTransaction().begin();
            manager.persist(course);
            manager.getTransaction().commit();
            return true;
        }catch (Exception e){
            return false;
        }
    }

    @Override
    public boolean update(Course course) {
        try{
            manager.getTransaction().begin();
            manager.merge(course);
            manager.getTransaction().commit();
            return true;
        }catch (Exception e){
            return false;
        }
    }

    @Override
    public boolean delete(Course course) {
        try{
            manager.getTransaction().begin();
            manager.remove(course);
            manager.getTransaction().commit();
            return true;
        }catch (Exception e){
            return false;
        }
    }
}
public class JDBCInscriptionRepository implements InscriptionRepository {
    private final EntityManager manager;

    public JDBCInscriptionRepository(EntityManager manager) {
        this.manager = manager;
    }

    @Override
    public Inscription getById(Integer id) {
        return manager.find(Inscription.class, id);
    }

    @Override
    public List<Inscription> getAll() {
        return manager.createQuery("select i from Inscription i", Inscription.class).getResultList();

    }

    @Override
    public boolean save(Inscription inscription) {
        try{
            manager.getTransaction().begin();
            manager.persist(inscription);
            manager.getTransaction().commit();
            return true;
        }catch (Exception e){
            return false;
        }
    }


    @Override
    public boolean delete(Inscription inscription) {
        try{
            manager.getTransaction().begin();
            manager.remove(inscription);
            manager.getTransaction().commit();
            return true;
        }catch (Exception e){
            return false;
        }
    }
}