O gerenciamento de chaves estrangeiras em ORMLite é um pouco diferente do que normalmente é feito em outros frameworks de ORM, como o Hibernate. Basicamente, são utilizadas as seguintes anotações para este gerenciamento:
Obs.: O ORMLite suporta apenas que as coleções sejam: ForeignCollection ou Collection, pois outros tipos são muito “pesados” e com diversas funcionalidades a mais para suportar. Outro detalhe é que, para que o ORMLite consiga identificar os relacionamentos, todos devem ser bi-direcionais, ou seja, Para cada coleção mapeada com ForeignCollectionField, o objeto referenciado deve conter uma referencia a classe que mantém a coleção.
O ORMLite provê algumas funcionalidades interessantes para lidar com objetos e coleções estrangeiras, dentre estas funcionalidades, eu citarei três neste post. Seguem:
Utilizando as anotações acima fica bastante intuitiva a criação de relacionamentos OneToMany, OneToOne e ManyToOne.
Usuario:
[cc lang=”java” width=”100%”]
@DatabaseTable(tableName = “USUARIO”)
public class Usuario {
/** The id. */
@DatabaseField(columnName = “id”, id = true, generatedId = true)
private int id;
/** The login. */
@DatabaseField(columnName = “login”, canBeNull = false)
private String login;
/** The nome. */
@DatabaseField(columnName = “nome”, canBeNull = false)
private String nome;
/** The idade. */
@DatabaseField(columnName = “idade”, dataType = DataType.INTEGER,
canBeNull = false)
private int idade;
@DatabaseField(columnName = “setor”, foreign = true)
private Setor setor;
[/cc]
Post
[cc lang=”java” width=”100%”]
@DatabaseTable(tableName = “POST”)
public class Post {
/** The id. */
@DatabaseField(columnName = “id”, id = true, generatedId = true)
private Long id;
/** The titulo. */
@DatabaseField(columnName = “titulo”, canBeNull = false)
private String titulo;
/** The conteudo. */
@DatabaseField(columnName = “conteudo”, canBeNull = false)
private String conteudo;
/** The usuario. */
@DatabaseField(canBeNull = false, foreign = true)
private Usuario usuario;
[/cc]
Setor
[cc lang=”java” width=”100%”]
@DatabaseTable(tableName = “SETOR”)
public class Setor {
@DatabaseField(id = true, generatedId = true, columnName = “id”)
private Long id;
@DatabaseField(columnName = “nome”, canBeNull = false)
private String nome;
@ForeignCollectionField(eager = true)
private Collection usuarios;
// private ForeignCollection;
[/cc]
Para a criação de relacionamentos ManyToMany, entretanto, deve ser criada uma outra entidade que gerencie estes relacionamentos, como no código a seguir.
Funcionario
[cc lang=”java” width=”100%”]
@DatabaseTable(tableName = “FUNCIONARIO”)
public class Funcionario {
@DatabaseField(id = true, generatedId = true, columnName = “id”)
private Long id;
@DatabaseField(columnName = “nome”, canBeNull = false)
private String nome;
[/cc]
Projeto
[cc lang=”java” width=”100%”]
@DatabaseTable(tableName = “PROJETO”)
public class Projeto {
@DatabaseField(id = true, generatedId = true, columnName = “id”)
private Long id;
@DatabaseField(columnName = “nome”, canBeNull = false)
private String nome;
[/cc]
ProjetoFuncionario
[cc lang=”java” width=”100%”]
@DatabaseTable(tableName = “PROJETO_FUNCIONARIO”)
public class ProjetoFuncionario {
/** The id. */
@DatabaseField(columnName = “id”, id = true, generatedId = true)
private Long id;
/** The funcionario. */
@DatabaseField(
columnName = “funcionario_id”, canBeNull = false,
uniqueCombo = true)
private Funcionario funcionario;
/** The projeto. */
@DatabaseField(
columnName = “projeto_id”, canBeNull = false, uniqueCombo = true)
private Projeto projeto;
[/cc]
Infelizmente a criação de relacionamentos ManyToMany no ORMLite é um pouco precária. É preciso tomar cuidado com o gerenciamento destes relacionamentos e é importante que alguns cuidados sejam tomados, como definir as propriedades canBeNull e uniqueCombo para true, fornecendo um pouco mais de consistência ao código e ao banco.
Este foi o quarto post sobre Databases no Android, espero que tenham gostado. Quaisquer dúvidas, sugestões e/ou reclamações, comentem!
_________________________________________
Lucas Oliveira – Analista Programador na redspark.
Bacharel em Sistemas de Informação pela Universidade de São Paulo.
@OliveiraLima_
Muito boa explicação, Simples, clara e direta.
Minha dúvida é quanto a anotação na tabela ProjetoFuncionario:
os atributos funcionario_id e projeto_id são primary keys também? Pois a tag “foreign = true” não é informada.
Como o ormlite trata isso?
Olá Fábio!
Como eu disse no post, o ORMLite não dá um bom suporte aos relacionamentos ManyToMany. Desta forma, este relacionamento está sendo feito ‘na mão’ (por isso a utilização de um campo ‘id’ na entidade ProjetoFuncionario).
Para conferir maior consistencia aos dados, utilize as tags “canBeNull = false” e “uniqueCombo = true”. Estas tags garantirão que sempre existam um projeto e um funcionario no relacionamento, e também que sejam únicos. Esta tarefa deveria ser feita pelo framework, mas, infelizmente, ainda não existe este suporte.
Att,
Lucas Oliveira – Analista Programador na DClick.
Bacharel em Sistemas de Informação pela Universidade de São Paulo.
@OliveiraLima_
Entendido mestre, seria fácil se um ManyToMany fosse da mesma forma que no Hibernate, mas paciencia né ,a tecnologia é nova ainda…
@ManyToMany(mappedBy = “habilidadeList”)
private List alunoList;
—
@JoinTable(name = “alunohabilidade”, joinColumns = {
@JoinColumn(name = “PESSOA_ID”,
referencedColumnName = “PESSOA_ID”)},
inverseJoinColumns = {
@JoinColumn(name = “HABILIDADE_ID”,
referencedColumnName = “HABILIDADE_ID”)})
@ManyToMany
private List habilidadeList;
Att.
Gostaria de saber se com anotacoes jpa (http://www.slideshare.net/lucasaquiles/orm-android) o relacionamento many2many fica mais elegante. Faça o teste e post para nós.