Saving ID of a table with two Primary Keys with Hibernate

1

Hello, I'm having a problem saving data to a last table. Well, this table has two foreign keys and the same ones are primary keys:

WhengoingtotheController,savethetable,Iusethefollowingcodes:

itv.setId();itv.setIngresso(ing);itv.setVenda(ven);itv.setItvqtde(Integer.valueOf(request.getParameter("txtqtde")));

    itvDao.salvarItemVenda(itv);
    response.sendRedirect("my-tickents-buy.jsp");

Here is my ItemVendaDao:

 public void salvarItemVenda(ItemVenda itv){


    try {

    s = new ConnectionFactory().getSessionFactory();
    tx = s.beginTransaction();
    s.save(itv);
    tx.commit();
    s.close();

    JOptionPane.showMessageDialog(null, "Item venda salva com sucesso");


    } catch (Exception e) {

        tx.rollback();

      JOptionPane.showMessageDialog(null, "Erro ao salvar item venda" +e.getMessage());
      s.close();


    }


}

What do I need to put in itv.setId ()? When mapping it creates this method to save the Id of the sales item, where the ID of the sales item are two: the object of the ticket and the object of the sale, both are already being saved above with the code:

 itv.setIngresso(ing);
    itv.setVenda(ven);

Again, what do you need to put in itv.setId () ?

Here is ItemVenda.java (mapped automatically by hibernate)

public class ItemVenda  implements java.io.Serializable {


 private ItemVendaId id;
 private Ingresso ingresso;
 private Venda venda;
 private int itvqtde;

public ItemVenda() {
}

public ItemVenda(ItemVendaId id, Ingresso ingresso, Venda venda, int itvqtde) {
   this.id = id;
   this.ingresso = ingresso;
   this.venda = venda;
   this.itvqtde = itvqtde;
}

public ItemVendaId getId() {
    return this.id;
}

public void setId(ItemVendaId id) {
    this.id = id;
}
public Ingresso getIngresso() {
    return this.ingresso;
}

public void setIngresso(Ingresso ingresso) {
    this.ingresso = ingresso;
}
public Venda getVenda() {
    return this.venda;
}

public void setVenda(Venda venda) {
    this.venda = venda;
}
public int getItvqtde() {
    return this.itvqtde;
}

public void setItvqtde(int itvqtde) {
    this.itvqtde = itvqtde;
}

And the SalesId.java Item is as follows:

public class ItemVendaId  implements java.io.Serializable {


 private int itvvencodigo;
 private int itvingressocodigo;

public ItemVendaId() {
}

public ItemVendaId(int itvvencodigo, int itvingressocodigo) {
   this.itvvencodigo = itvvencodigo;
   this.itvingressocodigo = itvingressocodigo;
}

public int getItvvencodigo() {
    return this.itvvencodigo;
}

public void setItvvencodigo(int itvvencodigo) {
    this.itvvencodigo = itvvencodigo;
}
public int getItvingressocodigo() {
    return this.itvingressocodigo;
}

public void setItvingressocodigo(int itvingressocodigo) {
    this.itvingressocodigo = itvingressocodigo;
}
    
asked by anonymous 29.05.2016 / 23:37

3 answers

1

Initially, I will recommend you to have a primary key for each table. this primary key would be an ID field.

If you need your foreign keys to be unique in the table, use the UNIQUE attribute.

I will recommend you to use JPA annotations in your tables to assist Hibernate (if you are already using xml I recommend switching to Notes):

@Entity
public class ItemVenda  implements Serializable {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    @JoinColumn(name = "ingresso_id")
    private Ingresso ingresso;

    @ManyToOne
    @JoinColumn(name = "venda_id")
    private Venda venda;

    private int qtde;

    //getters e setters omitidos
}

You would also have the Sale and Entry classes with their respective fields. And I would have only these three tables. The ItemVend table would have the fields: id, ingresso_id, venda_id, qtde

Always letting Hibernate take care of this for you.

In this case your setId () method of the ItemVenda class would only be used in update cases.

    
30.05.2016 / 00:12
1

If the set of two or more columns that, in combination, will never be repeated, you do not need (and should not) create an extra column just to serve as the primary key (as @ Shura16 suggested). You will only be creating a totally unnecessary column for only its ease in development and running away from performance and good data integrity in the database.

In your case, you need to create a compound key. That simple. There are two ways to do this in JPA. One is through IdClass and the other, which I recommend, is through EmbeddedId and Embeddable.

Let's say you have a Class A, a Class B, and a third Class C where your primary key is made up of the Class A and B union.

It would look like this:

Class A:

@Entity
@Table(name = "CLASSE_A")
public class ClasseA {

    @Id
    @Column(name = "CLASSE_A_ID")
    private Long id;

}

Class B:

@Entity
@Table(name = "CLASSE_B")
public class ClasseB {

    @Id
    @Column(name = "CLASSE_B_ID")
    private String id;

}

Before creating class C, you should create a class that will incorporate Class A and Class B. This class will represent your composite key.

Class C PK:

@Embeddable
public class ClasseCPK {

    @Column(name = "CLASSE_A_ID", nullable = false)
    private Long classeAId;

    @Column(name = "CLASSE_B_ID", nullable = false)
    private String classeBId;

}

Notice the @Embeddable annotation in ClassCPK. This is to inform the JPA that this class will serve as a composite key. Note that your attributes are only a reference to the type of the Class A and B attributes. That is, Long and String.

Finally our Class C will look like this:

Class C:

@Entity
@Table(name = "CLASSE_C")
public class ClasseC {

    @EmbeddedId
    private ClasseCPK pk = new ClasseCPK();

    @ManyToOne
    @JoinColumn(name = "CLASSE_A_ID", referencedColumnName = "CLASSE_A_ID", nullable = false, updatable = false, insertable = false)
    private ClasseA classeA;

    @ManyToOne
    @JoinColumn(name = "CLASSE_B_ID", referencedColumnName = "CLASSE_B_ID", nullable = false, updatable = false, insertable = false)
    private ClasseB classeB;

}

And this completes the mapping.

One more detail. Just have Hibernate create the tables / columns for you if your project is small / amateur. If it is a large and important project, such as for a financial institution and the like, never let Hibernate interfere with the database structure, as this same database can (and most likely will) be used on other systems and in different languages .

Bonus: If an entity references you and another that has a compound key, you should use the @JoinColumns annotation.

    
02.06.2016 / 14:40
0

Hello,

Responding directly to your question ".. what do I need to put in itv.setId ()?"

According to your code this ID is made up of a ItemVendaId object, so just instantiate it at the time of recording that everything should work.

As you have not shown the code for the Inbound and Selling classes, I'm kicking the names of their ID's. Here's an example:

itv.setId(new ItemVendaId(ven.getitvvencodigo(), ing.getitvingressocodigo()));
itv.setIngresso(ing);
itv.setVenda(ven);
itv.setItvqtde(Integer.valueOf(request.getParameter("txtqtde")));
itvDao.salvarItemVenda(itv);
response.sendRedirect("my-tickents-buy.jsp");

In any case, like other colleagues who answered before, I do not recommend this kind of mapping.

    
02.06.2016 / 17:19