2009-12-18 19 views
5

Ho le classi di entità di seguito. Quando un utente si registra per la prima volta, vengono forniti solo il nome utente e la password, quindi l'elenco degli account (profili di pensiero) è vuoto. Successivamente, quando aggiungono un account, l'oggetto utente viene aggiornato nel client, passato al server e quindi viene chiamato entityManager.merge (utente). Quando l'utente viene unito, l'account viene aggiunto 6 volte al database e l'indirizzo fornito viene aggiunto tre volte. Non sono sicuro del perché. Vorrei che l'account venisse aggiunto una volta e un solo indirizzo da aggiungere. Qualche idea su cosa potrebbe accadere?JPA Merge sta causando duplicati

@Entity 
public class User implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="id") 
    private int id; 

    @OneToMany(cascade=CascadeType.ALL) 
    @JoinTable(name="user_accounts") 
    private List<Account> accounts; 

    //...getters and setters ... 
} 




@Entity 
public class Account implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="id") 
    private long id; 

    @ManyToOne(cascade=CascadeType.ALL) 
    @JoinColumn(name="address") 
    private Address address; 

    //...getters and setters... 

} 



@Entity 
public class Address implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="id") 
    private int id; 

    @Column(name="street") 
    private String street; 

    @Column(name="city") 
    private String city; 

    @Column(name="state") 
    private String state; 

    @Column(name="zip") 
    private String zip; 

    //...getters and setters... 
} 
+0

È possibile eliminare cose come @Column (name = "id") o @Column (name = "zip") se non si cambia il nome. – whiskeysierra

+0

il server live ha come impostazione predefinita tutti i nomi di tabella e colonna di maiuscole e il mio server di test ha il valore predefinito in lettere minuscole, quindi è sembrato più semplice modificare le impostazioni. – chris

+0

Hai trovato una soluzione? –

risposta

0

Hai provato a:

persist(address) 
account.setAddress(address) 
persist(account) 
user.setAccount(account) 
merge(user) 

credo perché indirizzo e conto hanno generato id e si specifica cascata causare questo problema.

1

Questo è un problema noto con l'unione in cui le raccolte sono elenchi. Sfortunatamente adesso la vera soluzione: HHH-5855

+0

Risolto nella versione 5.0.8 – aorticDefiance

0

La mia soluzione a questo problema era di aggiungere una funzione aggiuntiva al controller che aggiornasse la riga con un'istruzione SQL nativa. Dal momento che il mio codice ha aggiornato parte o chiave (una lunga storia, ma ha funzionato sorprendentemente bene), dovevo assicurarmi che non stavo cercando il record basato sui nuovi valori nel pojo. Ecco il codice:

public void editSQLUpdate(Reportinfo reportinfo) throws NonexistentEntityException, Exception { 
    EntityManager em = null; 
    try { 
     em = getEntityManager(); 
     em.getTransaction().begin(); 
     String qry = "UPDATE `boeaudit`.`reportinfo` " 
       + "SET " 
       + "`author` = '" + reportinfo.getAuthor() + "'," 
       + "`db_account` = '" + reportinfo.getDbAccount() + "'," 
       + "`db_schema_name` = '" + reportinfo.getDbSchemaName() + "'," 
       + "`descriptions` = '" + reportinfo.getDescriptions() + "'," 
       + "`DLL` = '" + reportinfo.getDll() + "'," 
       + "`parent_folder` = " + reportinfo.getParentFolder() + "," 
       + "`path` = '" + reportinfo.getPath() + "'," 
       + "`report_title` = '" + reportinfo.getReportTitle() + "'," 
       + "`report_id` = " + reportinfo.getReportinfoPK().getReportId() + "," 
       + "`env` = " + reportinfo.getReportinfoPK().getEnv() + "," 
       + "`db_server` = '" + reportinfo.getReportinfoPK().getDbServer() + "'," 
       + "`seq` = " + reportinfo.getReportinfoPK().getSeq() 
       + " WHERE `report_id` = " + reportinfo.getReportinfoPK().getReportId() 
       + " AND `env` = " + reportinfo.getReportinfoPK().getEnv() 
       + " AND `db_server` = '-'" //this is the initial value of the record and the update value differs, so if we pass the new value the record will not be found. ;) 
       + " AND `seq` = "+ reportinfo.getReportinfoPK().getSeq(); 
     Query nq = em.createNativeQuery(qry); 
     int outcome = nq.executeUpdate(); //not doing anything with outcome, but should be used to determine the result of the operation... 
     em.getTransaction().commit(); 
    } catch (Exception ex) { 
     String msg = ex.getLocalizedMessage(); 
     if (msg == null || msg.length() == 0) { 
      ReportinfoPK id = reportinfo.getReportinfoPK(); 
      if (findReportinfo(id) == null) { 
       throw new NonexistentEntityException("The reportinfo with id " + id + " no longer exists."); 
      } 
     } 
     throw ex; 
    } finally { 
     if (em != null) { 
      em.close(); 
     } 
    } 
} 
Problemi correlati