2013-03-19 18 views
13

ho una relazione molti-a-uno che voglio essere annullabile:Non può fare rapporto @ManyToOne annullabile

@ManyToOne(optional = true) 
@JoinColumn(name = "customer_id", nullable = true) 
private Customer customer; 

Purtroppo, APP continua a impostare la colonna nel mio database come NOT NULL. Qualcuno può spiegarlo? C'è un modo per farlo funzionare? Nota che utilizzo JBoss 7, JPA 2.0 con Hibernate come provider di persistenza e un database di PostgreSQL 9.1.

EDIT:

ho trovato la causa del mio problema. A quanto pare è dovuto al modo in cui ho definito la chiave primaria nell'entità riferimento Customer:

@Entity 
@Table 
public class Customer { 
    @Id 
    @GeneratedValue 
    @Column(columnDefinition="serial") 
    private int id; 
} 

Sembra che usando @Column(columnDefinition="serial") per la chiave primaria imposta automaticamente le chiavi esterne che fanno riferimento al NOT NULL nel database. È davvero questo il comportamento previsto quando si specifica il tipo di colonna come serial? C'è un modo per abilitare le chiavi esterne nullable in questo caso?

Grazie in anticipo.

risposta

9

Ho trovato la soluzione al mio problema. Il modo in cui la chiave primaria è definita nell'entità Customer va bene, il problema si trova nella dichiarazione della chiave esterna. Dovrebbe essere dichiarato così:

@ManyToOne 
@JoinColumn(columnDefinition="integer", name="customer_id") 
private Customer customer; 

Infatti, se l'attributo viene omesso columnDefinition="integer" volontà chiave esterna essere automaticamente impostato come colonna di origine: un seriale non nullo con la sua sequenza. Ovviamente questo non è ciò che vogliamo perché vogliamo solo fare riferimento all'ID auto-incrementato, non crearne uno nuovo.

Inoltre, sembra che l'attributo name=customer_id sia richiesto anche durante l'esecuzione di alcuni test. In caso contrario, la colonna chiave esterna verrà comunque impostata come colonna di origine. Questo è un comportamento strano secondo me. Commenti o ulteriori informazioni per chiarire questo sono i benvenuti!

Infine, il vantaggio di questa soluzione è che l'ID viene generato dal database (non da JPA) e quindi non ci dobbiamo preoccupare quando si inseriscono i dati manualmente o tramite script che spesso si verificano durante la migrazione o la manutenzione dei dati .

0

Questo è molto strano.

In JPA il parametro nullable è true per impostazione predefinita. Uso sempre questo tipo di configurazione e funziona perfettamente. Se provi a salvare un'entità, dovrebbe avere successo.

Hai provato a eliminare la tabella creata per questa relazione? Forse hai una tabella legacy con quella colonna?

O forse dovresti provare a trovare la soluzione su altri blocchi di codice, perché questa è la configurazione corretta.

Nota: ho provato questa configurazione su PostgreSQL con JPA2 e Hibernate.

EDIT

In questo caso forse si può provare un po 'diversa definizione della chiave primaria.

Ad esempio è possibile utilizzare la definizione in questo modo:

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
@Column() 
private Long id; 

e PostgreSQL genererà

id bigint NOT NULL 
-- with constraint 
CONSTRAINT some_table_pkey PRIMARY KEY (id) 

Se questo è abbastanza buono si può provare questa soluzione.

+0

Questo è davvero una soluzione che ho considerato. Sfortunatamente questo non abilita la generazione di ID dal database stesso, ed è una funzionalità di cui ho bisogno quando inserisco i dati manualmente (per esempio con import.sql di hibernate). Fortunatamente immagino che sto per trovare una soluzione. Sto solo facendo dei test e se avrà successo pubblicheremo la soluzione. Grazie per l'aiuto. – vcattin

7

mi sono imbattuto in questo problema, ma sono stato in grado di risolvere in questo modo:

@ManyToOne 
@JoinColumn(nullable = true) 
private Customer customer; 

Forse il problema emerso dal dichiarare @ManyToOne(optional = true)

+6

'nullable = false' ?? 'False'? Perché 'false', non' true'? – Andremoniy

+0

sicuramente dovrebbe essere 'nullable = true' – artificis

Problemi correlati