2013-02-22 12 views
6

Questo sono i miei soggetti:JPA molti-a-molti Registrazione entità tabella con composto chiave "id nullo generato"

public class Account extends AbstractEntity<Long> { 

    @Id 
    @SequenceGenerator(name = "accountSequence", sequenceName = "SQ_ACCOUNTS", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "accountSequence") 
    @Column(name = "ACC_ID", nullable = false) 
    private Long id; 
... 
} 

public class Integration extends AbstractEntity<Long> { 

    @Id 
    @SequenceGenerator(name = "integrationSequence", sequenceName="SQ_INTEGRATIONS", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "integrationSequence") 
    @Column(name = "INT_ID", nullable = false) 
    private Long id; 
... 
public void addIntegration(Integration integration) { 
     IntegrationAccount association = new IntegrationAccount(); 
      // This does not help 
     //association.setIntAccountsPK(new IntAccountsPK(integration.getId(), this.getId())); 
     association.setAccount(this); 
     association.setIntegration(integration); 
     this.integrationAccounts.add(association); 
     integration.getIntAccountsCollection().add(association); 
    } 
} 

e questo è entità per unirsi a tavola

@Entity 
@Table(name = "INT_ACCOUNTS") 
public class IntegrationAccount { 

    @EmbeddedId 
    protected IntAccountsPK intAccountsPK; 

    @JoinColumn(name = "ACC_ID", referencedColumnName = "ACC_ID", insertable = false, updatable = false) 
    @ManyToOne 
    private Account account; 

    @JoinColumn(name = "INT_ID", referencedColumnName = "INT_ID", insertable = false, updatable = false) 
    @ManyToOne 
    private Integration integration; 
... 
} 
@Embeddable 
public class IntAccountsPK implements Serializable { 

    @Column(name = "INT_ID", nullable = false) 
    private Long intId; 

    @Column(name = "ACC_ID", nullable = false) 
    private Long accId; 
... 
} 

e quando lo faccio :

account.addIntegrations(integrations.getTarget()); 
account.setCustomer(customer); 
accountService.save(account); 

ho ottenuto questo nel mio ceppo causato da: org.hibernate.id.IdentifierGenerationException: ha generato nulla id per: classe com.dhl.dcc.domain.IntegrationAccount

Non ho molte conoscenze su questo tipo di mappatura, puoi dirmi come migliorare questa mappatura (l'entità per la tabella di join deve essere preservata) e come salvare l'account con integrazioni correlate? Grazie.

risposta

1

È possibile creare un campo ID per IntegrationAccount e quindi creare un vincolo univoco per i due campi.

@Entity 
@Table(name = "INT_ACCOUNTS", 
     [email protected](columnNames={"ACC_ID", "INT_ID"})) 
public class IntegrationAccount { 

    @Id 
    private Long id; 

    @JoinColumn(name = "ACC_ID", referencedColumnName = "ACC_ID", insertable = false, updatable = false) 
    @ManyToOne 
    private Account account; 

    @JoinColumn(name = "INT_ID", referencedColumnName = "INT_ID", insertable = false, updatable = false) 
    @ManyToOne 
    private Integration integration; 
... 
} 

Funziona come un fascino!

+0

Come un incantesimo come hai detto, grazie. Ho dovuto rimuovere anche "insertable = false, updatable false". – DominikM

9

So che questa domanda è già stata contrassegnata come risolta ma non concordo con la risposta accettata. Questa risposta modifica il datamodel aggiungendo una colonna inutile (il nuovo id) nella tabella INT_ACCOUNTS. C'è un altro modo per risolvere questo problema in Hibernate senza modificare il datamodel:

@Entity 
@Table(name = "INT_ACCOUNTS") 
public class IntegrationAccount implements Serializable { 

    @Id 
    @ManyToOne 
    @JoinColumn(name = "INT_ID_FK") 
    private Integration integration; 

    @Id 
    @ManyToOne 
    @JoinColumn(name = "ACC_ID_FK") 
    private Account account; 
} 

@Entity 
@Table(name = "INTEGRATIONS") 
public class Integration { 

    @Id 
    @SequenceGenerator(name = "integrationSequence", sequenceName = "SQ_INTEGRATIONS", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "integrationSequence") 
    @Column(name = "INT_ID") 
    private Long id; 
} 

@Entity 
@Table(name = "ACCOUNTS") 
public class Account { 

    @Id 
    @SequenceGenerator(name = "accountSequence", sequenceName = "SQ_ACCOUNTS", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "accountSequence") 
    @Column(name = "ACC_ID") 
    private Long id; 
} 
+0

La soluzione senza modificare la datamodel sarebbe molto meglio. Quando lo faccio a modo tuo sto ottenendo 'Hibernate: insert into integrazione valori (nome) Hibernate (?): (?) I valori inserire in considerazione (nome) Exception in thread "main" java.lang.NullPointerException \t a org.hibernate.type.descriptor.java.AbstractTypeDescriptor.extractHashCode (AbstractTypeDescriptor.java:88) \t a org.hibernate.type.AbstractStandardBasicType.getHashCode (AbstractStandardBasicType.java:201) \t a org.hibernate.type.AbstractStandardBasicType .getHashCode (AbstractStandardBasicType.java:205) ' – DominikM

+0

Strano. Ha funzionato perfettamente per me. Ho aggiunto il resto della mappatura che ho usato per ricreare il tuo caso di test. Puoi darmi maggiori informazioni sull'errore che stai ottenendo ora? – overmeulen

Problemi correlati