bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


hibernate

Diferències

Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.

Enllaç a la visualització de la comparació

Següent revisió
Revisió prèvia
hibernate [2022/11/24 06:59]
albert_palacios_jimenez creat
hibernate [2022/11/24 08:24] (actual)
albert_palacios_jimenez [Configuració de Hibernate, arxiu "hibernate.properties"]
Línia 1: Línia 1:
-====== SQLite a Java ======+====== Hibernate ======
  
 {{tag> #FpInfor #Dam #DamMp06 #DamMp06Uf2 #DamMp06Uf02}} {{tag> #FpInfor #Dam #DamMp06 #DamMp06Uf2 #DamMp06Uf02}}
Línia 5: Línia 5:
  
 ---- ----
- 
-==== Exemples ==== 
- 
-Els arxius ./run.sh i .\run.bat tenen el codi per fer anar els exemples des de la línia de comandes amb versions modernes de Java (per sistemes Unix o Windows respectivament) 
- 
-Als exemples, cada vegada s'esborra i crea la base de dades com a nova 
- 
-Fa servir “@hibernate.argfile” per configurar els paràmetres de .java que permeten compilar i fer anar Hibernate 
- 
- 
  
 ==== ORMs i JPA ==== ==== ORMs i JPA ====
Línia 40: Línia 30:
 - URI de la base de dades - URI de la base de dades
  
-La configuració de "hibernate.properties" per MySQL:+== La configuració de "hibernate.properties" per MySQL: ==
  
 (Cal canviar DB_USER i DB_PASSWORD pels valors corresponents a la connexió ...) (Cal canviar DB_USER i DB_PASSWORD pels valors corresponents a la connexió ...)
Línia 54: Línia 44:
 </code> </code>
  
-La configuració de "hibernate.properties" per SQLite:+== La configuració de "hibernate.properties" per SQLite: ==
  
 (Amb SQLite s’especifica l’arxiu a utilitzar, en aquest cas "database.db") (Amb SQLite s’especifica l’arxiu a utilitzar, en aquest cas "database.db")
Línia 75: Línia 65:
  
 <code xml> <code xml>
-<?xml version = "1.0" encoding = "utf-8"?>+<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 <hibernate-configuration> <hibernate-configuration>
   <session-factory>   <session-factory>
-     <!-- List of XML mapping files --> +     <mapping resource="Employee.hbm.xml"/> 
-     <mapping resource = "Employee.hbm.xml"/> +     <mapping class="Contact"/>
-     <mapping class = "Contact"/>+
   </session-factory>   </session-factory>
 </hibernate-configuration> </hibernate-configuration>
Línia 99: Línia 88:
  
 <code xml> <code xml>
-<?xml version = "1.0" encoding = "utf-8"?>+<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE hibernate-mapping PUBLIC  <!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> "-//Hibernate/Hibernate Mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 <hibernate-mapping> <hibernate-mapping>
-  <class name = "Employee" table = "employee"> +  <class name="Employee" table="employee"> 
-     <meta attribute = "class-description">+     <meta attribute="class-description">
         This class contains the employee detail.         This class contains the employee detail.
      </meta>      </meta>
-     <id name = "id" type = "int" column = "id">+     <id name="id" type="int" column="id">
         <generator class="native"/>         <generator class="native"/>
      </id>      </id>
-     <property name = "firstName" column = "first_name" type = "string"/> +     <property name="firstName" column="first_name" type="string"/> 
-     <property name = "lastName" column = "last_name" type = "string"/> +     <property name="lastName" column="last_name" type="string"/> 
-     <property name = "salary" column = "salary" type = "int"/>+     <property name="salary" column="salary" type="int"/>
   </class>   </class>
 </hibernate-mapping> </hibernate-mapping>
Línia 133: Línia 122:
  
 @Entity @Entity
-@Table(name = "contact")+@Table(name="contact")
 public class Contact { public class Contact {
  
    @Id    @Id
-   @Column(name = "id")+   @Column(name="id")
    @GeneratedValue(strategy=GenerationType.AUTO) // L’id es genera automàticament    @GeneratedValue(strategy=GenerationType.AUTO) // L’id es genera automàticament
    private long id;    private long id;
  
-   @Column(name = "name")+   @Column(name="name")
    private String name;    private String name;
 </code> </code>
Línia 157: Línia 146:
 - Delete - Delete
  
 +Exemple d'arxiu Manajer.java
 +
 +<code java>
 +import java.io.Serializable;
 +import java.util.Collection;
 +import java.util.List;
 +import java.util.Set;
 +
 +import org.hibernate.HibernateException;
 +import org.hibernate.SQLQuery;
 +import org.hibernate.Session; 
 +import org.hibernate.Transaction;
 +import org.hibernate.boot.registry.StandardServiceRegistry;
 +import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 +import org.hibernate.SessionFactory;
 +import org.hibernate.cfg.Configuration;
 +
 +public class Manager {
 +
 +    private static SessionFactory factory; 
 +    
 +    public static void createSessionFactory() {
 +
 +        try {
 +            Configuration configuration = new Configuration();
 +            configuration.configure();
 +            StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
 +            configuration.getProperties()).build();
 +            factory = configuration.buildSessionFactory(serviceRegistry);
 +        } catch (Throwable ex) { 
 +            System.err.println("Failed to create sessionFactory object." + ex);
 +            throw new ExceptionInInitializerError(ex); 
 +        }
 +    }
 +
 +    public static void close () {
 +        factory.close();
 +    }
 +  
 +    public static Employee addEmployee(String firstName, String lastName, int salary){
 +        Session session = factory.openSession();
 +        Transaction tx = null;
 +        Employee result = null;
 +        try {
 +            tx = session.beginTransaction();
 +            result = new Employee(firstName, lastName, salary);
 +            session.save(result); 
 +            tx.commit();
 +        } catch (HibernateException e) {
 +            if (tx!=null) tx.rollback();
 +            e.printStackTrace(); 
 +            result = null;
 +        } finally {
 +            session.close(); 
 +        }
 +        return result;
 +    }
 +
 +    public static Contact addContact(String lname, String lmail){
 +        Session session = factory.openSession();
 +        Transaction tx = null;
 +        Contact result = null;
 +        try {
 +            tx = session.beginTransaction();
 +            result = new Contact(lname, lmail);
 +            session.save(result); 
 +            tx.commit();
 +        } catch (HibernateException e) {
 +            if (tx!=null) tx.rollback();
 +            e.printStackTrace(); 
 +            result = null;
 +        } finally {
 +            session.close(); 
 +        }
 +        return result;
 +    }
 +
 +    public static <T> T getById(Class<? extends T> clazz, long id){
 +        Session session = factory.openSession();
 +        Transaction tx = null;
 +        T obj = null;
 +        try {
 +            tx = session.beginTransaction();
 +            obj = clazz.cast(session.get(clazz, id)); 
 +            tx.commit();
 +        } catch (HibernateException e) {
 +            if (tx!=null) tx.rollback();
 +            e.printStackTrace(); 
 +        } finally {
 +            session.close(); 
 +        }
 +        return obj;
 +    }
 +    
 +    public static void updateContact(long contactId, String name, String email, Set<Employee> employees){
 +        Session session = factory.openSession();
 +        Transaction tx = null;
 +        try {
 +            tx = session.beginTransaction();
 +            Contact obj = (Contact) session.get(Contact.class, contactId); 
 +            obj.setName(name);
 +            obj.setEmail(email);
 +            obj.setEmployees(employees);
 +            session.update(obj); 
 +            tx.commit();
 +        } catch (HibernateException e) {
 +            if (tx!=null) tx.rollback();
 +            e.printStackTrace(); 
 +        } finally {
 +            session.close(); 
 +        }
 +    }
 +
 +    public static void updateEmployee(long employeeId, String firstName, String lastName, int salary){
 +        Session session = factory.openSession();
 +        Transaction tx = null;
 +        try {
 +            tx = session.beginTransaction();
 +            Employee obj = (Employee) session.get(Employee.class, employeeId); 
 +            obj.setFirstName(firstName);
 +            obj.setLastName(lastName);
 +            obj.setSalary(salary);
 +            session.update(obj); 
 +            tx.commit();
 +        } catch (HibernateException e) {
 +            if (tx!=null) tx.rollback();
 +            e.printStackTrace(); 
 +        } finally {
 +            session.close(); 
 +        }
 +    }
 +  
 +    public static <T> void delete(Class<? extends T> clazz, Serializable id){
 +        Session session = factory.openSession();
 +        Transaction tx = null;
 +        try {
 +            tx = session.beginTransaction();
 +            T obj = clazz.cast(session.get(clazz, id)); 
 +            session.delete(obj); 
 +            tx.commit();
 +        } catch (HibernateException e) {
 +            if (tx!=null) tx.rollback();
 +            e.printStackTrace(); 
 +        } finally {
 +            session.close(); 
 +        }
 +    }
 +
 +    public static <T> Collection<?> listCollection(Class<? extends T> clazz) {
 +        return listCollection(clazz, "");
 +    }
 +
 +    public static <T> Collection<?> listCollection(Class<? extends T> clazz, String where){
 +        Session session = factory.openSession();
 +        Transaction tx = null;
 +        Collection<?> result = null;
 +        try {
 +            tx = session.beginTransaction();
 +            if (where.length() == 0) {
 +                result = session.createQuery("FROM " + clazz.getName()).list(); 
 +            } else {
 +                result = session.createQuery("FROM " + clazz.getName() + " WHERE " + where).list();
 +            }
 +            tx.commit();
 +        } catch (HibernateException e) {
 +            if (tx!=null) tx.rollback();
 +            e.printStackTrace(); 
 +        } finally {
 +            session.close(); 
 +        }
 +        return result;
 +    }
 +
 +    public static <T> String collectionToString(Class<? extends T> clazz, Collection<?> collection){
 +        String txt = "";
 +        for(Object obj: collection) {
 +            T cObj = clazz.cast(obj);
 +            txt += "\n" + cObj.toString();
 +        }
 +        if (txt.substring(0, 1).compareTo("\n") == 0) {
 +            txt = txt.substring(1);
 +        }
 +        return txt;
 +    }
 +
 +    public static void queryUpdate (String queryString) {
 +        Session session = factory.openSession();
 +        Transaction tx = null;
 +        try {
 +            tx = session.beginTransaction();
 +            SQLQuery query = session.createSQLQuery(queryString);
 +            query.executeUpdate();
 +            tx.commit();
 +        } catch (HibernateException e) {
 +            if (tx!=null) tx.rollback();
 +            e.printStackTrace(); 
 +        } finally {
 +            session.close(); 
 +        }
 +    }
 +
 +    public static List<Object[]> queryTable (String queryString) {
 +        Session session = factory.openSession();
 +        Transaction tx = null;
 +        List<Object[]> result = null;
 +        try {
 +            tx = session.beginTransaction();
 +            SQLQuery query = session.createSQLQuery(queryString);
 +            @SuppressWarnings("unchecked")
 +            List<Object[]> rows = query.list();
 +            result = rows;
 +            tx.commit();
 +        } catch (HibernateException e) {
 +            if (tx!=null) tx.rollback();
 +            e.printStackTrace(); 
 +        } finally {
 +            session.close(); 
 +        }
 +        return result;
 +    }
 +
 +    public static String tableToString (List<Object[]> rows) {
 +        String txt = "";
 +        for (Object[] row : rows) {
 +            for (Object cell : row) {
 +                txt += cell.toString() + ", ";
 +            }
 +            if (txt.length() >= 2 && txt.substring(txt.length() - 2).compareTo(", ") == 0) {
 +                txt = txt.substring(0, txt.length() - 2);
 +            }
 +            txt += "\n";
 +        }
 +        if (txt.length() >= 2) {
 +            txt =  txt.substring(0, txt.length() - 2);
 +        }
 +        return txt;
 +    }
 +}
 +</code>
 ==== Hibernate, transactions ==== ==== Hibernate, transactions ====
  
Línia 171: Línia 399:
 <code java> <code java>
    public static Employee addEmployee(String firstName, String lastName, int salary){    public static Employee addEmployee(String firstName, String lastName, int salary){
-       Session session = factory.openSession(); +       Session session=factory.openSession(); 
-       Transaction tx = null; +       Transaction tx=null; 
-       Employee result = null;+       Employee result=null;
        try {        try {
-           tx = session.beginTransaction(); +           tx=session.beginTransaction(); 
-           result = new Employee(firstName, lastName, salary);+           result=new Employee(firstName, lastName, salary);
            session.save(result);            session.save(result);
            tx.commit();            tx.commit();
Línia 182: Línia 410:
            if (tx!=null) tx.rollback();            if (tx!=null) tx.rollback();
            e.printStackTrace();            e.printStackTrace();
-           result = null;+           result=null;
        } finally {        } finally {
            session.close();            session.close();
Línia 209: Línia 437:
  
 @Entity @Entity
-@Table(name = "Contact",  +@Table(name="Contact",  
- uniqueConstraints = {@UniqueConstraint(columnNames = "id")})+ uniqueConstraints={@UniqueConstraint(columnNames="id")})
 public class Contact implements Serializable { public class Contact implements Serializable {
  
  @Id  @Id
- @Column(name = "id", unique = true, nullable = false)+ @Column(name="id", unique=true, nullable=false)
  @GeneratedValue(strategy=GenerationType.IDENTITY) // L'id es genera automàticament  @GeneratedValue(strategy=GenerationType.IDENTITY) // L'id es genera automàticament
  private long contactId;  private long contactId;
  
- @Column(name = "name")+ @Column(name="name")
  private String name;  private String name;
  
- @Column(name = "email")+ @Column(name="email")
  private String email;  private String email;
  
- @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE}) 
- @JoinTable(name = "Employee_Contact",  + @JoinTable(name="Employee_Contact",  
- joinColumns = {@JoinColumn(referencedColumnName = "id")},  + joinColumns={@JoinColumn(referencedColumnName="id")},  
- inverseJoinColumns = {@JoinColumn(referencedColumnName = "id")})+ inverseJoinColumns={@JoinColumn(referencedColumnName="id")})
  private Set<Employee> employees; // Ha de tenir getter i setter perquè s'encarrega de la taula relacional N:N  private Set<Employee> employees; // Ha de tenir getter i setter perquè s'encarrega de la taula relacional N:N
  
Línia 233: Línia 461:
  
  public Contact(String name, String email) {  public Contact(String name, String email) {
- this.name = name; + this.name=name; 
- this.email = email;+ this.email=email;
  }  }
  
Línia 242: Línia 470:
  
  public void setContactId(long id) {  public void setContactId(long id) {
- this.contactId = id;+ this.contactId=id;
  }  }
  
Línia 250: Línia 478:
  
  public void setName(String name) {  public void setName(String name) {
- this.name = name;+ this.name=name;
  }  }
  
Línia 258: Línia 486:
  
  public void setEmail(String email) {  public void setEmail(String email) {
- this.email = email;+ this.email=email;
  }  }
  
Línia 266: Línia 494:
  
  public void setEmployees (Set<Employee> employees) {  public void setEmployees (Set<Employee> employees) {
- this.employees = employees;+ this.employees=employees;
  }  }
  
  public List<Object[]> queryEmployees () {  public List<Object[]> queryEmployees () {
- long id = this.getContactId(); + long id=this.getContactId(); 
- return Manager.queryTable("SELECT DISTINCT e.* FROM Employee_Contact ec, Employee e WHERE e.id = ec.employees_id AND ec.contacts_id = " + id);+ return Manager.queryTable("SELECT DISTINCT e.* FROM Employee_Contact ec, Employee e WHERE e.id=ec.employees_id AND ec.contacts_id=" + id);
  }  }
  
  @Override  @Override
     public String toString () {     public String toString () {
- String str = Manager.tableToString(queryEmployees());+ String str=Manager.tableToString(queryEmployees());
       return this.getContactId() + ": " + this.getName() + ", " + this.getEmail() + ", Employees: [" + str + "]";       return this.getContactId() + ": " + this.getName() + ", " + this.getEmail() + ", Employees: [" + str + "]";
     }     }
Línia 313: Línia 541:
 <code xml> <code xml>
 <hibernate-mapping> <hibernate-mapping>
- <class name = "Cart" table = "Cart"> + <class name="Cart" table="Cart"> 
-  <meta attribute = "class-description">CD</meta>+  <meta attribute="class-description">CD</meta>
   <id name="cartId" type="long" column="cartId">   <id name="cartId" type="long" column="cartId">
     <generator class="native"/>     <generator class="native"/>
Línia 336: Línia 564:
  
      public Cart() {}      public Cart() {}
-     public Cart(String type) { this.type = type; }+     public Cart(String type) { this.type=type; }
  
      // Getters i Setters      // Getters i Setters
Línia 345: Línia 573:
 <code xml> <code xml>
 <hibernate-mapping> <hibernate-mapping>
-  <class name = "Item" table = "Item"> +  <class name="Item" table="Item"> 
-    <meta attribute = "class-description">AB</meta>+    <meta attribute="class-description">AB</meta>
     <id name="itemId" type="long" column="id">     <id name="itemId" type="long" column="id">
     <generator class="native"/>     <generator class="native"/>
Línia 367: Línia 595:
  
    public Item() { }    public Item() { }
-   public Item(String name) { this.name = name; }+   public Item(String name) { this.name=name; }
  
      // Getters i Setters      // Getters i Setters
Línia 379: Línia 607:
 <code java> <code java>
 @Entity @Entity
-@Table(name = "Cart")+@Table(name="Cart")
 public class Cart implements Serializable { public class Cart implements Serializable {
      
      @Id      @Id
-     @GeneratedValue(strategy = GenerationType.AUTO) +     @GeneratedValue(strategy=GenerationType.AUTO) 
-     @Column(name = "cartId", unique = true, nullable = false)+     @Column(name="cartId", unique=true, nullable=false)
      private long cartId;      private long cartId;
    
-     @Column(name = "type")+     @Column(name="type")
      private String type;       private String type; 
  
      @OneToMany      @OneToMany
-     @JoinColumn(name = "cartId")+     @JoinColumn(name="cartId")
      private Set<Item> items;      private Set<Item> items;
  
Línia 397: Línia 625:
      
      public Cart(String type) {      public Cart(String type) {
-        this.type = type;+        this.type=type;
      }      }
      // Getters, Setters i toString      // Getters, Setters i toString
Línia 406: Línia 634:
 <code java> <code java>
 @Entity @Entity
-@Table(name = "Item")+@Table(name="Item")
 public class Item implements Serializable { public class Item implements Serializable {
  
Línia 420: Línia 648:
    @ManyToOne    @ManyToOne
    @JoinColumn(name="cartId", insertable=false,     @JoinColumn(name="cartId", insertable=false, 
-   updatable = false)+   updatable=false)
    private Cart cart;    private Cart cart;
  
Línia 426: Línia 654:
  
    public Item(String name) {    public Item(String name) {
-       this.name = name;+       this.name=name;
    }    }
      // Getters, Setters i toString      // Getters, Setters i toString
 } }
 </code> </code>
 +
 +==== Tipus de relacions N:N ManyToMany ====
 +
 +Són aquelles que creen una relació entre múltiples elements de múltiples d’altres taules. Necessiten una taula extra per mantenir la relació. Per exemple:
 +
 +- Una supermercat té N treballadors i alguns d'aquests són N clients
 +
 +- Múltiples comandes es relacionen amb múltiples clients
  
 ==== Exemple N:N ManyToMany amb ".hbm.xml" ==== ==== Exemple N:N ManyToMany amb ".hbm.xml" ====
Línia 437: Línia 673:
 <code xml> <code xml>
 <hibernate-mapping> <hibernate-mapping>
- <class name = "Contact" table = "Contact">+ <class name="Contact" table="Contact">
   <meta attribute="class-description">AB</meta>   <meta attribute="class-description">AB</meta>
    <id name="contactId" type="long" column="id">    <id name="contactId" type="long" column="id">
Línia 462: Línia 698:
    public Contact() { }    public Contact() { }
    public Contact(String name, String email) {    public Contact(String name, String email) {
-       this.name = name; +       this.name=name; 
-       this.email = email;+       this.email=email;
    }    }
      // Getters i Setters      // Getters i Setters
Línia 507: Línia 743:
 <code java> <code java>
 @Entity @Entity
-@Table(name = "Contact", +@Table(name="Contact", 
-   uniqueConstraints = {@UniqueConstraint(columnNames = "id")})+   uniqueConstraints={@UniqueConstraint(columnNames="id")})
 public class Contact implements Serializable { public class Contact implements Serializable {
  
    @Id    @Id
-   @Column(name = "id", unique = true, nullable = false)+   @Column(name="id", unique=true, nullable=false)
    @GeneratedValue(strategy=GenerationType.IDENTITY)     @GeneratedValue(strategy=GenerationType.IDENTITY) 
  
    private long contactId;    private long contactId;
  
-   @Column(name = "name")+   @Column(name="name")
    private String name;    private String name;
  
-   @Column(name = "email")+   @Column(name="email")
    private String email;    private String email;
  
-   @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) +   @ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE}) 
-   @JoinTable(name = "Employee_Contact", +   @JoinTable(name="Employee_Contact", 
-       joinColumns = {@JoinColumn(referencedColumnName = "id")}, +       joinColumns={@JoinColumn(referencedColumnName="id")}, 
-       inverseJoinColumns = {@JoinColumn(referencedColumnName = "id")})+       inverseJoinColumns={@JoinColumn(referencedColumnName="id")})
    private Set<Employee> employees;     private Set<Employee> employees; 
    // Constructors, Getters, Setters i toString    // Constructors, Getters, Setters i toString
Línia 535: Línia 771:
 <code java> <code java>
 @Entity @Entity
-@Table(name = "Employee", +@Table(name="Employee", 
-  uniqueConstraints = {@UniqueConstraint(columnNames = "id")})+  uniqueConstraints={@UniqueConstraint(columnNames="id")})
 public class Employee implements Serializable { public class Employee implements Serializable {
      
      @Id      @Id
-     @GeneratedValue(strategy = GenerationType.IDENTITY) +     @GeneratedValue(strategy=GenerationType.IDENTITY) 
-     @Column(name = "id", unique = true, nullable = false)+     @Column(name="id", unique=true, nullable=false)
      private long employeeId;      private long employeeId;
    
-     @Column(name = "firstName")+     @Column(name="firstName")
      private String firstName;      private String firstName;
          
-     @Column(name = "lastName")+     @Column(name="lastName")
      private String lastName;        private String lastName;  
          
-     @Column(name = "salary")+     @Column(name="salary")
      private int salary;       private int salary; 
  
-     @ManyToMany(mappedBy = "employees")  +     @ManyToMany(mappedBy="employees")  
      private Set<Contact> contacts;       private Set<Contact> contacts; 
  
Línia 560: Línia 796:
 </code> </code>
  
 +==== Exemples ====
 +
 +Els arxius ./run.sh i .\run.bat tenen el codi per fer anar els exemples des de la línia de comandes amb versions modernes de Java (per sistemes Unix o Windows respectivament)
 +
 +Als exemples, cada vegada s'esborra i crea la base de dades com a nova
 +
 +Fan servir “@hibernate.argfile” per configurar els paràmetres de .java que permeten compilar i fer anar Hibernate
 +
 +{{ :hibernate-exempleintroduccio.zip |}}
 +
 +{{ ::hibernate-exemplejpa_onetomany.zip |}}
 +
 +{{ ::hibernate-exemplejpa_manytomany.zip |}}
 +
 +{{ ::hibernate-exemplexml_onetomany.zip |}}
 +
 +{{ ::hibernate-exemplexml_manytomany.zip |}}
 +
 +{{ ::hibernate-exemplemysql.zip |}}
  
hibernate.1669273185.txt.gz · Darrera modificació: 2022/11/24 06:59 per albert_palacios_jimenez