Como mapear uma entidade para usar uma FK de outra classe já existente? [RESOLVIDO]

10 respostas
Metallica

Oi pessoal,

To achando difícil até descrever o problema, mas deve ser simples: tenho uma classe Arquivo e outra Extensao. Um Arquivo tem uma Extensão mas a Extensão nada sabe do Arquivo.
Como faço pro Arquivo usar tal extensão que já existe na tabela Extensão? Por exemplo se eu salvo dois arquivos com extensão mp3, ele cria 2 linhas mp3 na tabela de extensão, cada uma com um ID. Quero reusar essa linha com o ID do mp3.

@Entity
public class Arquivo {
    @Id
    @GeneratedValue
    private Long id;
    ...
    @OneToOne
    Extensao extensaoDoArquivo; //OneToOne nao parece fazer sentido...
}
@Entity
public class Extensao {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
    
    @Column(length=3)
    private String tipo;
}

Imagino que tenha alguma coisa a ver com o @GeneratedValue, não? Só que nenhum parece ser o que eu quero.

Thanks!

10 Respostas

R

vc quer criar uma relacao 1 pra 1 entre as duas entidades aonde a entidade Arquivo tera um id (fk) corresponde da entidade Extensao…e isso?

lelodois

Seria bom fazer um diagrama para entendermos :wink:

quikkoo

a explicação foi pouco confusa mesmo, mas me parece q a intensão é usar um relacionamento de muitos pra um, já que varios arquivos podem possuir uma mesma extenção, sendo assim o mapeamento da classe Arquivo ficaria assim:

@Entity
public class Arquivo
{
	@Id @GeneratedValue
	private Long id;
	...
	@ManyToOne
	Extensao extensao;
	...
}

pra mais detalhes olha aqui: hibernate > annotations > entity mapping association

flw, t+

Metallica

Opa pessoal,

Aqui está uma foto pra vocês entenderem melhor:


(A primeira tabela é o jeito que eu quero, e a segunda tabela é o jeito que está ficando. Percebam como a extensão está repetindo valores.)

Ou seja, eu quero que o arquivo tenha o ID de uma extensão, mas a extensão não pode se repetir e criar uma extensão pra cada arquivo.

quikkoo

como eu disse na postagem acima, é um relacionamento de muitos pra um…

Metallica

Então, eu já tinha tentado fazer @ManyToOne também. E dava o mesmo problema. Várias extensões repetidas na tabela de Extensao, exatamente como a tabela da figura mostra.

Tem certeza que é só mapear muitos para um?

Minhas classes ficaram assim:

@Entity
public class Extensao implements Serializable{
    @Id
    @GeneratedValue
    private Long id;
    
    @Column(name="extensao")
    private String tipo;
   //getters e setters
}
@Entity
@Table(name="DVD_ARQUIVOS")
public class Arquivo {
    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    private Extensao extensao; 
    //getters e setters
}
Metallica

Então, ninguém sabe mesmo? Ainda não consegui resolver isso.

lelodois

Segue…

Extensao.java

@Entity
public class Extensao implements Serializable {

	@Id
	@GeneratedValue
	private Long id;

	@Column(name = "extensao", unique = true)
	private String tipo;

	@OneToMany(mappedBy = "extensao", fetch = FetchType.LAZY)
	private Set<Arquivo> arquivos = new HashSet<Arquivo>();
  
        // get and set
}

Arquivo

@Entity
@Table
public class Arquivo implements Serializable {
	
	@Id
	@GeneratedValue
	private Long id;

	@Column
	private String nome;

	@Column
	private Float tamanho;

	@ManyToOne
	@ForeignKey(name = "extensao_fk")
	private Extensao extensao;

        // get and set
}

Execução

@Override
	public void execute(Session session) {
		List<File> files = Arrays.asList(new File("c:\\teste").listFiles());

		Transaction transacao = session.beginTransaction();
		for (File file : files) {

			// Não faça isto em casa 
			// #bug (se exister no arquivo + de um "."
			String[] nomeExtensao = file.getName().split("\\.");
			String nomeArquivo = nomeExtensao[0].toString();
			String nomeDaExtensao = nomeExtensao[1].toString();

			Extensao extensao = this.criarExtensao(nomeDaExtensao, session);
			Arquivo arquivo = new Arquivo(extensao, 899832.09F, nomeArquivo);

			extensao.getArquivos().add(arquivo);
			
			session.merge(arquivo);
		}
		transacao.commit();
	}

	private Extensao criarExtensao(String tipo, Session session) {
		Criteria crit = session.createCriteria(Extensao.class);
		Extensao obj = (Extensao) crit.add(Restrictions.ilike("tipo", tipo, MatchMode.EXACT)).uniqueResult();
		if (obj == null)
			obj = (Extensao) session.merge(new Extensao(tipo));
		return obj;
	}

}

Existem outras formas de fazer… mas esta é a q eu gosto :slight_smile:
Abraços

Metallica

Segue…

Existem outras formas de fazer… mas esta é a q eu gosto :slight_smile:
Abraços

Obrigadíssimo!
Funcionou certinho. Apesar de ser uma coisa tão comum em banco de dados, achei tão complicado em Hibernate.

lelodois

Segue…

Existem outras formas de fazer… mas esta é a q eu gosto :slight_smile:
Abraços

Obrigadíssimo!
Funcionou certinho. Apesar de ser uma coisa tão comum em banco de dados, achei tão complicado em Hibernate.

:slight_smile:

Criado 8 de agosto de 2010
Ultima resposta 24 de ago. de 2010
Respostas 10
Participantes 4