JPA List<Map mapping.. >

Asked

Viewed 634 times

11

I have the following problem and I would like some advice on the best approach:

Let’s assume you have a system that manages a school and would like to have the option for the system administrator in which it can register a modality/class that is and link prices according to the days of the week available for this class.

For example:

  • JPA class is available SECOND, FOURTH and SIXTH for 50 reais, or Tuesday and Thursday for 35 reais;
  • JSF class is available from MONDAY to FRIDAY for 80 reais, or Tuesday, Wednesday and Thursday for 40 reais.

That is, give the option for the administrator to create a price according to the days of the week. What would be the best option for JPA mapping?

Initially I created a Enum with every day of the week and thought to create something like a List<Map<List<DiasDaSemana>, Double>> precos, mixed-up right?

Does anyone have any idea what the best way to solve this is, and if this is an acceptable way, what kind of mapping would be? Through a @ElementCollection? Any help is welcome!

  • And if you encapsulate in a new object something like: List<Early Then you map each object normally without much confusion.

  • 3

    @Bruno, this seems to me more a question of database modeling than of JPA itself. We need to define first the set of tables that will store this information and then think about mapping with JPA.

4 answers

0

As stated in a comment, this problem is database modeling. After modeling the bank, you create JPA entities (although some tutorials of JPA and other Orms suggest otherwise...).

(Option 1)

In this case a way would be to create a table called Precopordia with columns/attributes ID_CURSO, DIA_SEMANA, VALUE. If DIA_SEMANA is not enough, you can create more complex items in this Enum, such as Terqui (Tuesday and Thursday), Segquasex (Monday, Wednesday and Friday) and Desegasex (Monday to Friday).

(Option 2)

But I have a more complete suggestion:

Create two separate concepts: one is the Course and the other is, shall we say, the Application or Instantiating or something (the name you can perfect).

The Course table/class would contain only immutable course data such as name, category, programmatic content, prerequisites.

On the other hand, the Application table/class would have a reference to the course (ID_CURSO) and add specific data for that instance of the course: start and end date, room number, teacher, days of the week, price. Look at it this way: the same course can be taught by different teachers, in different rooms and can have different prices depending on the period (summer or winter, Tuesday+Thursday or Monday+Wednesday, Saturdays only, etc.) and still be the same course!

You can stop here or, if necessary, we can now resume the initial idea and create Precopordia (or Precoporperiodo) that I suggested at the beginning. In this case Applicationsocurso would not have the price directly, but would reference a value corresponding to one of the existing options, making some joins.

There are some details that need to be refined. Ex.: Will the pre-term contain the date of application of the course? If it does not contain, how will the adjustments be made in the coming years? If so, is the Precoporperiodo table not quite the same as the existing Application table? In this case it would be enough for the Application itself... That’s the problem for us to think about :-)

Creating and naming concepts separately from the beginning, you will not have a structure List<Map<List<DiasDaSemana>, Double>> precos and yes List<AplicacaoCurso> cursos. Then you can create search methods like findByDiaDaSemana using SQL as required.

0

I had the idea to create a map for the options this way:

Map<String, Map<String,Double>> opções = new HashMap();

This way you can specify the courses on the external map and on the internal map specific the day of the week and the respective price.

0

I would do so:

class Courses{
    private Long id;
    private String title;

    ....

    private BigDecimal price_promotion;
    private BigDecimal price;

    ....

    public BigDecimal getPricePromotionSpecificDay(){
        Calendar c = Calendar.getInstance();
        Date d = new Date();

        c.setTime(d);

        if(c.get(Calendar.DAY_OF_WEEK) == 4 || c.get(Calendar.DAY_OF_WEEK) == 3){
            return price_promotion;
        }

        return price;
    }
}

when you make the call, just call this method.

0

I’d do it this way:

import java.math.BigDecimal;
import java.time.DayOfWeek;

public class Curso {
    private int id;
    private String nome;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getNome() {
        return nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
}

public class Preco {
    private int id;
    // já tem no Java, não tem porque criar outro enum
    private DayOfWeek diaDaSemana; 
    // nunca trabalhe com valores financeiros usando Double ou Float a perda de precisão pode te causar problemas, especialmente em relatários
    private BigDecimal preco;
    private Curso curso;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public DayOfWeek getDiaDaSemana() {
        return diaDaSemana;
    }
    public void setDiaDaSemana(DayOfWeek diaDaSemana) {
        this.diaDaSemana = diaDaSemana;
    }
    public BigDecimal getPreco() {
        return preco;
    }
    public void setPreco(BigDecimal preco) {
        this.preco = preco;
    }
    public Curso getCurso() {
        return curso;
    }
    public void setCurso(Curso curso) {
        this.curso = curso;
    } 
}

To access, use:

List<Preco> precos;

Browser other questions tagged

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