Arquivo da tag: Hibernate

JPA – Mapeamento com chave composta

Municipio

@Entity
@Table(name = "municipio")
public class Municipio {
 
	@EmbeddedId
	private MunicipioPK id;
 
	@Column(name = "DSC_MUNICIPIO")
	private String nome;
 
	@Column(name = "NUM_CEP")
	private Long cep;
 
	@ManyToOne
	@JoinColumn(name = "COD_UF", referencedColumnName = "COD_UF", insertable = false, updatable = false)
	private UnidadeFederacao uf;
}

MunicipioPK

@Embeddable
public class MunicipioPK implements Serializable {
 
	@Column(name = "COD_MUNICIPIO")
	private Integer idMunicipio;
 
	@Column(name = "COD_UF")
	private Integer idUnidadeFederacao;
}

UnidadeFederativa

@Entity
@Table(name = "unidade_federacao")
public class UnidadeFederacao {
 
	@Id
	@Column(name = "cod_uf")
	private Integer id;
 
	@Column(name = "dsc_uf")
	private String nome;
 
	@Column(name = "nom_sigla_uf")
	private String sigla;
 
	@OneToMany(mappedBy = "uf", fetch = FetchType.LAZY)
	private List<Municipio> municipios;
}

Hibernate – @ASSOCIATIONOVERRIDES @ATTRIBUTEOVERRIDES @EMBEDDABLE @EMBEDDED

With hibernate we can design domain class with many feature, now I will create some example to understanding about Embeddable Annotation, in final i will create some example to custom that Embeddable using Attribute overrides.

domain-design

I have Entity class with name Person, that class embed all properties from Address class, so all property in Address will be included into Person class. Address class has relation many to one with City class

City.java

package com.meng.test.hibernate.domain;

import javax.persistence.*;

@Entity
@Table(name = "CITY")
public class City {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "GEN_CITY_ID")
	@SequenceGenerator(name = "GEN_CITY_ID", sequenceName = "SEQ_CITY_ID", initialValue = 1, allocationSize = 1)
	@Column(name = "ID")
	private Long id;
	@Column(name = "NAME")
	private String name;

	// getter and setter

}

City class will create table with structure like below

mysql> desc city;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| ID    | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| NAME  | varchar(255) | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

Address.java

package com.meng.test.hibernate.domain;

import javax.persistence.*;

@Embeddable
public class Address {

	@Column(name = "STREET")
	private String street;
	@Column(name = "POSTAL_CODE")
	private String postalCode;
	@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
	@JoinColumn(name = "CITY_ID")
	private City city;

	// getter and  setter

}

Person.java

package com.meng.test.hibernate.domain;

import javax.persistence.*;

@Entity
@Table(name = "PERSON")
public class Person {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "GEN_PERSON_ID")
	@SequenceGenerator(name = "GEN_PERSON_ID", sequenceName = "SEQ_PERSON_ID", initialValue = 1, allocationSize = 1)
	@Column(name = "ID")
	private Long id;

	@Column(name = "NAME")
	private String name;

	@Embedded
	private Address address;

	// getter and setter

}

Person class will generate table with structure include Address properties like below

mysql> desc person;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| ID          | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| POSTAL_CODE | varchar(255) | YES  |     | NULL    |                |
| STREET      | varchar(255) | YES  |     | NULL    |                |
| NAME        | varchar(255) | YES  |     | NULL    |                |
| CITY_ID     | bigint(20)   | YES  | MUL | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

As we look in person table, all address class properties included into person class.

And now how we can custom column name

Employee.java

package com.meng.test.hibernate.domain;

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "GEN_EMPLOYEE_ID")
	@SequenceGenerator(name = "GEN_EMPLOYEE_ID", sequenceName = "SEQ_EMPLOYEE_ID", initialValue = 1, allocationSize = 1)
	@Column(name = "ID")
	private Long id;
	
	@Column (name = "NAME")
	private String name;
	
	@Embedded
	@AssociationOverrides({ 
        @AssociationOverride(name = "city", joinColumns =  @JoinColumn(name = "E_CITY_ID")) })
	@AttributeOverrides({
			@AttributeOverride(name = "street", column = @Column(name = "E_STREET")),
			@AttributeOverride(name = "postalCode", column = @Column(name = "E_POSTAL_CODE"))})
	private Address address;

	// getter and setter

}
mysql> desc employee;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| ID            | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| E_POSTAL_CODE | varchar(255) | YES  |     | NULL    |                |
| E_STREET      | varchar(255) | YES  |     | NULL    |                |
| NAME          | varchar(255) | YES  |     | NULL    |                |
| E_CITY_ID     | bigint(20)   | YES  | MUL | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

as we look in employee table, properties in Address class override with new name

Como pegar a conexão usando JPA ou Hibernate

Eu passei por um problema que era usar a mesma conexão que eu usava no projeto para usar no meu relatório com o ireports.
Para resolver esse problema usei esse código.

public class ReportsRepository {
 
    private EntityManager entityManager;
 
    public ReportsRepository(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
 
    public Connection getConnection() {
        try {
            EntityManagerImpl factory = (EntityManagerImpl) entityManager;
            SessionFactoryImpl sessionFactoryImpl = (SessionFactoryImpl) factory.getSession().getSessionFactory();
            return sessionFactoryImpl.getConnectionProvider().getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

@MappedSuperclass ou @Inheritance

Quando você usa a anotação @MappedSuperclass, quando gerar as tabelas ela não será gerada e sim as classes filhas dela exemplo:

@MappedSuperclass 
abstract class  Animal {}
 
@Entity
class Cao extends Animal {}
 
@Entity
class Gato extends Animal {}
 
@Entity
class Leao extends Animal {}

No banco as tabelas que vão ser criadas serão Cao, Gato e Leao. Caso você queira a a tabela de Animal sejá gerada então será preciso mudar a anotação para @Inheritance, que no caso tem três possíveis estratégias de mapeamento – INGLE TABLE, TABLE PER CLASS ou JOINED. Ficaria assim:

@Entity
@Inheritance(strategy = InheritanceType.JOINED) 
abstract class  Animal {}
 
@Entity
class Cao extends Animal {}
 
@Entity
class Gato extends Animal {}
 
@Entity
class Leao extends Animal {}