Map columns of separate tables into a single object and vice versa

Asked

Viewed 1,525 times

1

Situation 1

I have the following tables, very simple:

inserir a descrição da imagem aqui....................... inserir a descrição da imagem aqui

And I have the following classes:

Client:

@Entity
public class Cliente implements Serializable {

    private static final long serialVersionUID = 7402770378598465859L;

    private Short id;
    private String nome;

    @Column(name="data_nascimento")
    private LocalDate dataNascimento;

    private Contato contato;

    //Constructor
    // get e sets
}

Contact:

@Entity
public class Contato implements Serializable {

    private static final long serialVersionUID = -5040500676803061821L;

    private String telefone;
    private String celular;

    //Constructor
    // get e sets
}

Official:

@Entity
public class Funcionario implements Serializable{

    private static final long serialVersionUID = -5718684144972644433L;

    private Short id;
    private String nome;
    private String rg;
    private String cpf;
    private boolean ativo;
    private Contato contato;

    //Constructor
    // get e sets
}

Situation 2

I have the following tables, very simple:

inserir a descrição da imagem aqui

And I have the following classes:

Client:

@Entity
public class Cliente implements Serializable {

    private static final long serialVersionUID = 7402770378598465859L;

    private Short id;
    private String nome;

    @Column(name = "data_nascimento")
    private LocalDate dataNascimento;

    private String telefone;
    private String celular;

    // Constructor
    // get e sets
}

Official:

@Entity
public class Funcionario implements Serializable {

    private static final long serialVersionUID = -5718684144972644433L;

    private Short id;    
    private String nome;
    private String rg;
    private String cpf;
    private boolean ativo;
    private String telefone;
    private String celular;

    // Constructor
    // get e sets
}

Issues

1 - In "Situation 1", we have 2 tables and 3 classes, in which the properties telephone and cellular class Contact are represented as columns in tables Official and Client in the database, how this situation is mapped using JPA?

2 - In "Situation 2", we have 3 tables and 2 classes, in which the columns of the "Contact" table of the database are represented in the application as class properties Official and Client, how do I map using JPA in this situation?

3 - In the Customer class we have the property dataNascization which stores an object of the type java.time.LocalDate. To JPA(2.1) and/or Hibernate(4.3.5.Final) provides some annotation or other means for mapping this object? If not, there is some other alternative than to re-use the java.util.Date?

4 - This is a question of curiosity about SQL, the type attribute BIT currently has some difference from TINYINT(1)?

1 answer

1


Responding to situation 1 and 2:

What you need to solve situation 1 is in situation 2 and vice versa, that is, in situation 1 you have 2 tables and the code of situation 2 is noted for 2 entities. You also have the possibility, in situation 1, to create the Contact class without it is noted for JPA and make the others inherit from it. In situation 2, the attributes belong to the Contacts table, so they cannot be annotated in other entities. In that case do the following (alternative solution to situation 2):

  1. Create the entity Contact;
  2. Replace the phone and cell attributes of the classes with a variable of type Contact;
  3. Make the note using @Onetoone as it is in the relationship.

    @Entity
    public class Contato implements Serializable {
    
        private static final long serialVersionUID = -5040500676803061821L;
    
        private String telefone;
        private String celular;
    
        //Constructor
        // get e sets
    }
    
    @Entity
    public class Cliente implements Serializable {
    
        private static final long serialVersionUID = 7402770378598465859L;
    
        private Short id;
        private String nome;
    
        @Column(name="data_nascimento")
        @Temporal(DATE)
        private Calendar dataNascimento;
    
        @OneToOne(fetch=FetchType.LAZY)
        private Contato contato;
    
        //Constructor
        // get e sets
    }
    
    @Entity
    public class Funcionario implements Serializable{
    
        private static final long serialVersionUID = -5718684144972644433L;
    
        private Short id;
        private String nome;
        private String rg;
        private String cpf;
        private boolean ativo;
    
        @OneToOne(fetch=FetchType.LAZY)
        private Contato contato;
    
        //Constructor
        // get e sets
    }
    

Responding to 3, see that I changed the date of birth type to Calendar and put the @Temporal annotation.

About the BIT in relation to TINYINT(1) is that the BIT by default in some databases is recognized as a boolean field, that is, it will always accept 0 or 1 or FALSE or TRUE. On the other hand, TINYINT stores integer values greater than 1 or less than 0, depending on how it was defined, and even defining it thus TINYINT(1) does not change its behavior. So if you are going to work with boolean values, use BIT.

Note: If the relationship is 1 to 1, remove the Contact table from the database and place the attributes in the Customer and Employee. It will facilitate your side and prevent excessive use of Join. :D

Updated:

If you want to keep the table separate and use its attributes in the entities you can use the @Embeddable annotation.

Oracle Javadoc Embeddable

  • First of all, thank you for answering me. The question I asked is why I first created the Customer and Employee classes, however, these two classes had many similar attributes besides cell and phone (I only put these two attributes to simplify), so I first created the Contact class, putting the similar attributes on contact in this class to mitigate attribute redundancy, I had created the Address class, which also contains redundant attributes of the Employee and Client classes, but I did not ask the question to simplify it.

  • As in your observation, it is unnecessary to create an extra table for Contacts and the associations for this are 1-1, which could as you said yourself, occur performance loss. But in my case real, i still have the Address class, which has 7 redundant attributes of the Client, Employee and Request (address to send the request to) gathered there. In your opinion, in this my scenario, you think I better mitigate redundancy and create tables like Contact and Address(relationships for these classes are 1-1), or leave the tables with many redundant attributes?

  • 1

    Man, the advantage of not creating a Contact and Address table and not mapping them is that JPA will not do the automatic Joins, that is, increases the performance of the Framework. On counter-start, you will have many repeated attributes in your entities. I don’t know what to recommend to you, because both have their advantages and disadvantages.

  • One thing I forgot to mention, in the case of the date, you changed to Calendar which is not wrong, but as I read some things about the library java.time of Java 8 and because it has a number of advantages I wanted to use it in my project and wanted to know if there was an annotation that I could use to map the java.time.LocalDate, and not the java.util.Date or java.util.Calendar previous versions of Java.

  • 1

    I’ll be honest, I don’t work with Java 8 yet, but if I use it, they say Joda’s here to stay, but I don’t know about it. Another thing, talking about your separate entity, take a look at the @Embeddable annotation and how to work with it.

  • Dude, it was something like this I was looking for, the @Embeddable annotation makes it possible for me to separate the columns into distinct objects, like the Client table, and separate this into Client class and Address class, maintaining the cohesion of which Address class is intrinsic to the Client class.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.