2013-02-14 18 views
5

Mi chiedo solo se c'è un modo che io possa avere costruire la mia tabella di MySQL comeJPA + Hibernate: Come definire un vincolo di dover ON DELETE CASCADE

ALTER TABLE `USERINFO` 
    ADD CONSTRAINT `FK_USER_ID` FOREIGN KEY (`USERID`) REFERENCES `USERACCOUNT` (`USERID`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE; 

Tuttavia, ho ottenuto solo questo nella mia DDL quando Hibernate ++ inizia APP a costruire la mia tabella di aver "<property name="hibernate.hbm2ddl.auto" value="create" />"

ALTER TABLE `USERINFO` ADD CONSTRAINT `FK_USER_ID` FOREIGN KEY (`USERID`) REFERENCES `USERACCOUNT` (`USERID`); 

Nelle mie classi, ho questi configurazione di annotazione,

// UserAcc.java 
@Entity 
@Table(name = "USERACC") 
public class UserAcc implements Serializable { 

private static final long serialVersionUID = -5527566248002296042L; 

@Id 
@Column(name = "USERID") 
@GeneratedValue(strategy=GenerationType.AUTO) 
private Integer userId; 


@OneToOne(mappedBy = "userAcc") 
private UserInfo userInfo; 
.... 


public UserInfo getUserInfo() { 
    return userInfo; 
} 
public void setUserInfo(UserInfo userInfo) { 
    this.userInfo = userInfo; 
} 
... 

e,

// UserInfo.java 
@Entity 
@Table(name = "USERINFO") 
public class UserInfo implements Serializable { 

private static final long serialVersionUID = 5924361831551833717L; 

@Id 
@Column(name = "USERINFO_ID", nullable=false) 
@GeneratedValue(strategy=GenerationType.AUTO) 
private Integer userInfoId; 

@OneToOne(cascade = {CascadeType.ALL}) 
@JoinColumn(name="USERID", nullable=false) 
@ForeignKey(name = "FK_USER_ID") 
private UserAcc userAcc; 


public Integer getUserInfoId() { 
    return userInfoId; 
} 

public void setUserInfoId(Integer userInfoId) { 
    this.userInfoId = userInfoId; 
} 
... 

Si noti che, tavolo UserAccount è il/tabella principale genitore qui mentre UserInfo è una tabella estesa normalizzare ad un altro soggetto. Qualsiasi risposta sarebbe molto apprezzata. Sono solo curioso di sapere come è fatto, visto che amo lavorare anche su MySQL. Sono davvero abituato a cancellare un record dalla tabella genitore (USERACOUNT) che mi permetterebbe anche di mettere in cascata un record di delete thru dipendente dal record specifico da una tabella genitore/primaria.

Grazie!

+0

Hai trovato una soluzione a questo problema utilizzando jpa? Sto avendo lo stesso problema e non voglio usare una relazione bidirezionale, creando il recupero pigro sul genitore. –

risposta

5

JPA offre la possibilità di operazioni cascade (unire, persistere, aggiornare, rimuovere) alle entità associate. La logica è in JPA e non utilizza cascate di database.

Non esiste un modo conforme allo standard JPA per eseguire cascate con cascate di database. Se tali cascate sono preferite, dobbiamo ricorrere al costrutto specifico Hibernate: @OnDelete. Funziona almeno con @OneToMany, ma in passato c'erano alcuni problemi con @OneToOne e @OnDelete.

@OnDelete(action = OnDeleteAction.CASCADE) 
+1

Grazie Mikko. Ho provato a includere OnDelete con annotazioni JPA, non ha funzionato davvero. Ho una domanda, quando volevi manipolare il tuo database e volevo aggiungere ON DELETE CASCADE, in particolare MySQL, come gestirlo? – toytoy

5

Non ci sono mezzi puliti per farlo in JPA. Quanto segue ti porterà quello che vuoi ... Puoi usare CascadeType.DELETE, tuttavia questa annotazione si applica solo agli oggetti nello EntityManager, non al database. Si vuole essere sicuri che ON DELETE CASCADE sia stato aggiunto al vincolo del database. Per verificare, è possibile configurare JPA per generare un file ddl. Dai uno sguardo al file ddl, noterai che ON DELETE CASCADE non fa parte del vincolo. Aggiungi ON DELETE CASCADE all'effettivo SQL nel file ddl, quindi aggiorna lo schema del database dal ddl. Questo risolverà il tuo problema.

Questo link mostra come utilizzare ON DELETE CASCADE per CONSTRAINT in MySQL. Lo fai nel vincolo. Puoi anche farlo in una dichiarazione CREATE TABLE o ALTER TABLE. È probabile che JPA crei il vincolo in un'istruzione ALTER TABLE. Aggiungi semplicemente ON DELETE CASCADE a quella dichiarazione.

Si noti che alcuni implementatori JPA forniscono un mezzo per questa funzionalità.

Infine, Hibernate fornisce questa funzionalità utilizzando l'annotazione OnDelete(action = OnDeleteAction.CASCADE).

1

È possibile utilizzare l'annotazione Hibernate [email protected](action = OnDeleteAction.CASCADE) su UserAcc.userInfo:

public class UserAcc implements Serializable { 

... 

@OneToOne(mappedBy = "userAcc") 
@OnDelete(action = OnDeleteAction.CASCADE) 
private UserInfo userInfo; 

... 

questo genererà DDL ON DELETE CASCADE sulla chiave esterna nella UserInfo tavolo.

Problemi correlati