Map objects by Hibernate with "decentralized" data

2

I do not know if the decentralized title term is correct, if it is not someone feel free to change. But let's get down to business.

I have a scenario where I am developing a program that manages monitoring of an institution, in the classes of JavaEE and Hibernate we did the mapping of the right classes, I created the class Student, for example, I put all the attributes in it, relationships, etc. , follow the code:

Student.java

@Entity
public class Aluno implements Serializable {

    @Id
    @Column(length=11, nullable=false)
    private int cpf;

    @Column(nullable=false)
    private String nome;

    @Column(nullable=false)
    private int rg;

    @Column(length=11,nullable=false)
    private int matricula;

    @Temporal(TemporalType.DATE)
    private Date dataNascimento;

    /* RELACIONAMENTOS */

    @OneToMany(mappedBy="aluno")
    private List<Inscricao> inscricoes;

    @OneToMany(mappedBy="aluno")
    private List<Relatorio> relatorios;

    /* GETTERS AND SETTERS */
    ...
}

Beauty, working 100%, but this within the classroom, we are now going to the implementation part where we will consume data from the institution, only in their database does not have a Student table as I have in my class , in their bank there is a Student table that does not have the name of the student for example but contains the ID of a person, the name of the student is in the person table, and so on, the bank is fairly standardized.

Now in practice, how do I get to consume the data with my current class? What modifications do you make? How to say that the name attribute for example is in the person table? I researched but could not find, I do not know if I'm searching for the wrong terms, but if someone can help me, thankful.

    
asked by anonymous 14.12.2014 / 03:39

1 answer

1

For the name of the table, you can use the @Table annotation. You can also use @SecondaryTable or @SecondaryTables if the entity is divided into several separate tables. You can use @Inheritance , @DiscriminatorColumn and @DiscriminatorValue to map inheritance.

You should make your entity mapping reflect the database and vice versa. If this does not happen, one of the two should be changed. After all, the purpose of the entity and of the annotations is to accurately describe to Hibernate / JPA how object-relational mapping occurs, and therefore if its Aluno class is significantly different from that in the database, then one of the two should be changed to suit the other.

You can map views if necessary. The reason this is possible is that Hibernate / JPA can not (or rather does not need to) distinguish whether it is doing SELECT in a table or a view. However, if you do this, at the time it attempts to give INSERT , UPDATE or DELETE , you will have an exception, so only use this if you are sure that these operations should never occur. p>

Example of using @Table and @SecondaryTable :

@Entity
@Table(name = "xpto") // O nome da tabela no banco de dados é xpto, embora a entidade se chame Aluno.
@SecondaryTables({
    @SecondaryTable(name = "xpto2", pkJoinColumns = @PrimaryKeyJoinColumn(name = "ALUNO_ID"))
    @SecondaryTable(name = "xpto3", pkJoinColumns = @PrimaryKeyJoinColumn(name = "CHAVE"))
})
public class Aluno implements Serializable {

    @Column(table = "xpto")
    private String foo;

    @Column(table = "xpto2")
    private String bar;

    // ...
}

In this case, you are saying that the Aluno entity is in the xpto , xpto2 , and xpto3 tables, xpto being the main table. The corresponding tuples in the xpto2 and xpto3 table are found by their respective primary key fields (which must match xpto ). That is, there is a 1-to-1 relationship between the three (even if the database does not impose integrity constraint, since you are only saying this to Hibernate / JPA). That is, from the Hibernate / JPA point of view, the xpto2 and xpto3 tables have as PK, the% FK of%.

If the relationship between these tables is not as simple as that or the format of the keys differ from one to another, it may be best to use xpto or something else.

Example of using @OneToOne with @Inheritance strategy:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Pessoa implements Serializable {
    // ...
}

@Entity
public class Aluno extends Pessoa {
    // ...
}

@Entity
public class Professor extends Pessoa {
    // ...
}

That's why there is a table for JOINED , one for Pessoa and one for Aluno , where the primary key of the three have the same format (ie from the Hibernate / JPA perspective , The PK of Professor is FK of Aluno and the PK of Pessoa is FK of Professor also). And then:

  • Every tuple inserted in the Pessoa table is also in the Aluno table.
  • The entire tuple inserted in the Pessoa table is also in the Professor table.
  • If a tuple is in the Pessoa table, it may or may not be in Pessoa or Aluno .

Example of using Professor with @Inheritance strategy:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Pessoa implements Serializable {
    // ...
}

@Entity
public class Aluno extends Pessoa {
    // ...
}

@Entity
public class Professor extends Pessoa {
    // ...
}

This results in a table for TABLE_PER_CLASS and one for Aluno . There is no table for Professor . Basically the Pessoa mapping is copied-and-pasted into each of the subclasses.

Example of using Pessoa with @Inheritance strategy:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TIPO", discriminatorType = STRING, length = 20)
public class Pessoa implements Serializable {
    // ...
}

@Entity
@DiscriminatorValue("ALUNO")
public class Aluno extends Pessoa {
    // ...
}

@Entity
@DiscriminatorValue("PROF")
public class Professor extends Pessoa {
    // ...
}

This puts the SINGLE_TABLE s and Aluno s all in the same table, and this table must contain all fields of both Professor and Aluno . The Professor column in this example differentiates whether the tuple is a TIPO or a Aluno . If it is Professor is ALUNO . If it is Aluno is PROF .

    
14.12.2014 / 03:57