Spooky Exceptions (5) Caused by: org.postgresql.util.PSQLException: ERROR: column “date_start” is of type date but expression is of type character varying


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.

Du hast Fragen oder Anmerkungen? Kontakt: arndt@schoenb.de

,