Umgebung
- Wildfly 10
- EE7
- Postgres
- Eclipselink
Situation
Wenn wir versuchen ein abhängiges Objekt über Datenbankattribute vom Typ Date zu referenzieren (mindestens eines), kann dies zu Problemen führen. Wir haben folgende Abhängigkeit
@JoinColumns({ @JoinColumn(name = "mandator_id", referencedColumnName = "mandator_id", insertable = true, updatable = true), @JoinColumn(name = "date_start", referencedColumnName = "date_start", insertable = true, updatable = true) }) @ManyToOne private AccountingPeriod accountingPeriodEnd = null;
Es wird also auf ein Objekt vom Typ AccountingPeriod verwiesen. Beide Attribute für die Verbindung sind schreibend definiert. Versucht man nun diesen Wert mit null zu persistieren, kann es zu folgender Fehler-Meldung kommen
Caused by: org.postgresql.util.PSQLException: ERROR: column "date_start" is of type date but expression is of type character varying
Innerhalb des Mappings erkennt die JPA nicht den korrekten Typ. Je nach Datenbank, kann dies zu Problemen führen.
Lösung
Es muss das Date-Attribut „ausgelagert“ werden. Hierfür definieren wir
@Temporal(TemporalType.TIMESTAMP) @Column(name = "date_start") private Date dateEnd = null; @JoinColumns({ @JoinColumn(name = "mandator_id", referencedColumnName = "mandator_id", insertable = true, updatable = true), @JoinColumn(name = "date_start", referencedColumnName = "date_start", insertable = false, updatable = false) }) @ManyToOne private AccountingPeriod accountingPeriodEnd = null;
Im entsprechneden Setter müssen wir das korrekte Befüllen des Date-Attribits sicherstellen
public AccountingPeriod getAccountingPeriodEnd() { return this.accountingPeriodEnd; } public void setAccountingPeriodEnd(AccountingPeriod value) { this.accountingPeriodEnd = value; if (value != null) { this.setDateEnd(value.getDateStart()); } else { this.setDateEnd(null); } } protected Date getDateEnd() { return this.dateEnd; } private void setDateEnd(Date value) { this.dateEnd = value; }
Hierdurch ist der Typ eindeutig definiert und JPA hat keine Probleme mehr.