Linguagens orientadas a objeto utilizam atualmente frameworks ORM para persistir objetos no banco de dados relacional. Um clássico relacionamento entre duas tabelas em um banco de dados é feito através de uma chave primaria que contem um identificador em uma tabela e dados adicionais e uma chave estrangeira em outra tabela que define a referencia ao seu registro mestre, este tipo de referencia é comumente conhecido como referencia pai e filho ou mestre e detalhes. Ao longo dos anos os dados alimentados em tabelas mestre/detalhes foram inseridos através de scripts SQL escritos manualmente, ou seja se faz necessário que o desenvolvedor escreva um script pra inserir os dados na tabela mestre primeiro e depois escreva outro script para inserir os dados na tabela de detalhes, a chave estrangeira previne que somente seja inseridos dados na tabela de detalhes no qual possui uma referencia na tabela mestre, tornando assim o banco de dados integro.
Os frameworks modernos nos permitem persistir objetos utilizando a sintaxe da programação orientada a objeto de sua preferencia ao invés de usar scripts SQL tradicionais, pois estes serão criados automaticamente pelo próprio framework. Uma das vantagens de se usar este tipo de framework é que você pode persistir dados diretamente de seus objetos não precisando escrever linhas de código SQL. No entanto é preciso que você domine os conceitos exigidos pelo framework para criar cada tipo de recurso que a linguagem SQL oferece para que seu código rode redondo e com ótimo desempenho.
No caso do Hibernate é necessário que você utilize corretamente as anotações pra que o framework saiba como funciona o relacionamento entre as duas tabelas.
One To One: http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#d5e3678
One To One Mapping
1 – Primeiramente crie duas tabelas utilizando o script abaixo no banco de dados Oracle e crie sua foreign key adequadamente, caso a chave estrangeira esteja incorreta o Hibernate não conseguira utilizar o relacionamento adequadamente:
2 – Crie um novo projeto Java SE e utilize os códigos abaixo para suas respectivas classes. Atente-se para as anotações pois elas são importantes e precisam estar corretamente decoradas em seus atributos ou métodos, nunca misture as anotações entre atributos e métodos:
3 – Após rodar sua aplicação abra o Oracle SQL Developer e veja o conteúdo das duas tabelas. Você pode reparar que com apenas uma Sequence criando o identificador você automaticamente gravou os dados mestre/detalhes fazendo referencia ao seu ID:
Exemplo:
Neste exemplo criamos duas tabelas e uma chave estrangeira que faz referencia ao seu identificador criando um relacionamento mestre/detalhes. Utilizamos o framework Hibernate e seu relacionamento One To One para persistir dois objetos que foram mapeados adequadamente para salvar registros mestres e seus detalhes mantendo a integridade relacional no banco de dados.
SQL
-- Cria Sequence Participante
CREATE SEQUENCE SEQ_CARROS
START WITH 1
INCREMENT BY 1
NOCACHE
NOCYCLE;
-- Cria tabela de participantes
CREATE TABLE CARROS
(
ID_CARRO INTEGER NOT NULL
, DESCRICAO VARCHAR2(30) NOT NULL
, CONSTRAINT CARROS_PK PRIMARY KEY
(
ID_CARRO
)
ENABLE
);
-- Cria tabela de carro_detalhes
CREATE TABLE CARROS_DETALHES
(
ID_CARRO INTEGER NOT NULL
, MARCA VARCHAR2(30) NOT NULL
, MODELO VARCHAR2(30) NOT NULL
, ANO INTEGER NOT NULL
, CONSTRAINT CARROS_DETALHES_PK PRIMARY KEY
(
ID_CARRO
)
ENABLE
);
-- Cria Contraint chave estrangeira
ALTER TABLE CARROS_DETALHES ADD CONSTRAINT CARRO_FK
FOREIGN KEY (ID_CARRO) REFERENCES CARROS (ID_CARRO);
Java
Carros
package org.desenvolvimento.aberto;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name = "CARROS")
public class Carros {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CARROS")
@SequenceGenerator(name = "SEQ_CARROS", sequenceName = "SEQ_CARROS")
@Column(name = "ID_CARRO")
private int id_carro;
@Column(name = "DESCRICAO")
private String descricao;
// Cria instancia dos detalhes
@OneToOne(mappedBy= "carros", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "ID_CARRO")
private CarrosDetalhes carroDetalhes;
// Getters & Setters Carros
public int getId_carro() {
return id_carro;
}
public void setId_carro(int id_carro) {
this.id_carro = id_carro;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
// Getter & Setter detalhes
public CarrosDetalhes getCarroDetalhes() {
return carroDetalhes;
}
public void setCarroDetalhes(CarrosDetalhes carroDetalhes) {
this.carroDetalhes = carroDetalhes;
}
}
CarrosDetalhes
package org.desenvolvimento.aberto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
@Entity
@Table(name = "CARROS_DETALHES")
public class CarrosDetalhes {
@GenericGenerator(name = "generator", strategy = "foreign", parameters = @Parameter(name = "property", value = "carros"))
@Id
@GeneratedValue(generator = "generator")
@Column(name = "ID_CARRO")
private int id_carro;
@Column(name = "MARCA")
private String marca;
@Column(name = "MODELO")
private String modelo;
@Column(name = "ANO")
private int ano;
@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
private Carros carros;
public int getId_carro() {
return id_carro;
}
public void setId_carro(int id_carro) {
this.id_carro = id_carro;
}
public String getMarca() {
return marca;
}
public void setMarca(String marca) {
this.marca = marca;
}
public String getModelo() {
return modelo;
}
public void setModelo(String modelo) {
this.modelo = modelo;
}
public int getAno() {
return ano;
}
public void setAno(int ano) {
this.ano = ano;
}
public Carros getCarros() {
return carros;
}
public void setCarros(Carros carros) {
this.carros = carros;
}
}
Teste
package org.desenvolvimento.aberto;
import org.hibernate.Session;
public class Testar {
public static void main(String[] args) {
// Cria sessão
Session session = DBConexaoFactory.getSessionFactory().openSession();
// Cria transação
session.beginTransaction();
// Cria objeto de detalhes
CarrosDetalhes detalhes = new CarrosDetalhes();
detalhes.setMarca("Honda");
detalhes.setModelo("Civic");
detalhes.setAno(2015);
// Cria objeto carro
Carros carros = new Carros();
carros.setDescricao("Honda");
// adiciona detalhes ao carro
carros.setCarroDetalhes(detalhes);
detalhes.setCarros(carros);
// salva carro
session.save(carros);
// Confirma e encerra transação
session.getTransaction().commit();
}
}
DbConexaoFactory
package org.desenvolvimento.aberto;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class DBConexaoFactory {
private static final SessionFactory sessionFactory = buildSessionFactory();
// Constroi sessão
@SuppressWarnings("deprecation")
private static SessionFactory buildSessionFactory() {
try {
// buildSessionFactory não será utilizado em versões superiores
// Veremos outros métodos para criar um Factory
// Não é necessário incluir o "hibernate.cfg.xml" no configure()
// Incluímos somente a nível de fácil entendimento da chamada da
// configuração.
// Você pode retirar a chamada.
return new Configuration().configure("hibernate.cfg.xml")
.buildSessionFactory();
} catch (Throwable ex) {
// Em caso de erro
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
// Retorna Factory da sessão
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
// Encerra Sessão
public static void shutdown() {
getSessionFactory().close();
}
}
Hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.pool_size">10</property>
<property name="show_sql">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<mapping class="org.desenvolvimento.aberto.Carros" />
<mapping class="org.desenvolvimento.aberto.CarrosDetalhes" />
</session-factory>
</hibernate-configuration>














