JPA Postgresql/JPA/EclipseLink - Mapping Fehler?

Asperah

Mitglied
Guten Tag,

ich bin gerade ein wenig am Verzweifeln weil und wäre dankbar wenn mir jemand helfen könnte.

Ich nutze eine PostgreSQL Datenbank, Payara5 und Eclipselink.
Die Entitys habe ich mir mit JPA aus den Tabellen generieren lassen.
Ich versuche gerade eine Rest-Schnittstelle zu programmieren. Eigendlich klappt es auch ganz gut - so ziemlich zur Hälfte ganz gut. Wenn ich versuche die Daten mit nem GET-request auszulesen zeigt er so ca die Hälfte korrekt an, die andere Hälfte sind Null-Werte.

Hier mal der Code:

TestRessource
Java:
package services;

import java.sql.Timestamp;
import java.util.List;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import controller.TestDAO;
import model.Test;

@Path("/test")
public class TestRessource {
    @Inject
    TestDAO corapD;
    
    @Path("/gettest")
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getCorap() {
        List<Test> test = corapD.getTest();
        String scorap = "";
        Long id = 22L;
        Long testLong = 24L;
        Long status= 23L;
        Timestamp buchzeitstempel;
        
        for (Test item: test) {
            if (item.getStatus() != null) {
                status = item.getStatus();
                        }
            else status = 43L;
            System.out.println("Status: "+ status);
            
            testLong = item.getTestLong();
            if (testLong == null) scorap += "Stoffmain_id is null! ";
            else scorap += "Stoffmain_id ist not null! ";           

            testLong = item.getTestLong();
            buchzeitstempel = item.getBuchzeitstempel();
            
            scorap += "Id: "+id+", Jahr: "+item.getJahr()+", Buchzeitstempel: "+buchzeitstempel+", Authority: "+item.getAuthority()+ ", Status: " +status+ item.getStatus()+", "+"Buchperson: "+item.getBuchperson()+", Grounds_for_Concern: "+item.getGrounds()+", StoffmainId: "+testLong+"\n";
        };
        return scorap;
    }
    
    
    @Path("/gettest2")
    @GET
    @Produces(MediaType.APPLICATION_XML)
    public List<Test> getCor2() {
        List<Test> corap = corapD.getTest();

        return corap;
    }
}

Test Entity:
Java:
package model;

import java.io.Serializable;
import java.sql.Timestamp;

import javax.persistence.*;
import javax.xml.bind.annotation.XmlRootElement;

import rangetype.TSRange;

import java.sql.Date;


@XmlRootElement
@IdClass(TestPK.class)
@Entity
@Table(name="Test", schema="public")
@NamedQuery(name="Test.findAll", query="SELECT c FROM Test c")
public class Test implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private Long id;                        //funktioniert soweit
    @Id
    private Timestamp buchzeitstempel;        //funktioniert auch
    
    public Timestamp getBuchzeitstempel() {
        return buchzeitstempel;
    }

    public void setBuchzeitstempel(Timestamp buchzeitstempel) {
        this.buchzeitstempel = buchzeitstempel;
    }

    private String authority;            //funktioniert

    private String buchperson;            //jupp wird ausgegeben

    @Column(name="grounds")
    private Long grounds;                //gibt einen nullwert aus (in der Datenbank sind aber definitiv keine Nullwerte drin!)
    
    //@Embedded
    @Column(name="gueltigkeitszeitraum")
    private TSRange gueltigkeitszeitraum;    //'TSRange' ist noch ein weiteres Problem, dazu gleich mehr

    private Date jahr;                    //funktioniert nicht, nullwert wird ausgegeben

    @Column(name="status",columnDefinition="int8")
    private Long status;                //funktioniert nicht, nullwert wird ausgegeben

    private Long testLong;                 //funktioniert nicht, nullwert wird ausgegeben

    public Test() {
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getAuthority() {
        return this.authority;
    }

    public void setAuthority(String authority) {
        this.authority = authority;
    }

    public String getBuchperson() {
        return this.buchperson;
    }

    public void setBuchperson(String buchperson) {
        this.buchperson = buchperson;
    }


    public Long getGrounds() {
        return this.grounds;
    }

    public void setGrounds(Long grounds) {
        this.grounds = grounds;
    }

    public TSRange getGueltigkeitszeitraum() {
        return this.gueltigkeitszeitraum;
    }

    public void setGueltigkeitszeitraum(TSRange gueltigkeitszeitraum) {
        this.gueltigkeitszeitraum = gueltigkeitszeitraum;
    }

    public Date getJahr() {
        return this.jahr;
    }

    public void setJahr(Date jahr) {
        this.jahr = jahr;
    }

    public Long getStatus() {
        return this.status;
    }

    public void setStatus(Long status) {
        this.status = status;
    }

    public Long getTestLong() {
        return this.testLong;
    }

    public void setTestLong(Long TestLong) {
        this.testLong = TestLong;
    }
}

TestPK:
Code:
package model;

import java.io.Serializable;
import java.sql.Timestamp;

import javax.persistence.*;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@Embeddable
public class TestPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;
    @Column(name="id")
    private Long id;
    @Column(name="buchzeitstempel")
    private Timestamp buchzeitstempel;

    public TestPK() {
    }
    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Timestamp getBuchzeitstempel() {
        return this.buchzeitstempel;
    }
    public void setBuchzeitstempel(Timestamp buchzeitstempel) {
        this.buchzeitstempel = buchzeitstempel;
    }

    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (!(other instanceof TestPK)) {
            return false;
        }
        TestPK castOther = (TestPK)other;
        return
            this.id.equals(castOther.id)
            && this.buchzeitstempel.equals(castOther.buchzeitstempel);
    }

    public int hashCode() {
        final int prime = 31;
        int hash = 17;
        hash = hash * prime + this.id.hashCode();
        hash = hash * prime + this.buchzeitstempel.hashCode();
        
        return hash;
    }
}

TestDAO:
Java:
package controller;

import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import model.Test;
import shared.SingletonService;

@SingletonService
public class TestDAO {
    @Inject
    private EntityManager entityManager;
    
    public TestDAO() {};
    
    public List<Test> getTest(){
        TypedQuery<Test> testListe = entityManager.createQuery("SELECT c FROM Test c", Test.class);
        return testListe.getResultList();
    }
    
    public void save(Test t) {
        entityManager.persist(t);
    }
}

EntityManagerProducer:
Java:
package shared;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.*;
import javax.persistence.*;


@ApplicationScoped
public class EntityManagerProducer {
    @Produces
    @Default
    @PersistenceContext(unitName="sistestdb")
    private EntityManager em;
}

SingletonService Interface:
Java:
package shared;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Stereotype;
import javax.inject.Named;
import javax.transaction.Transactional;

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Stereotype
    @ApplicationScoped
    @Transactional
    @Named
public @interface SingletonService {

}

Die Felder sind in der Datenbank definitiv gefüllt, aber die Hälfte kommt nur als Null-Wert an.
Ich habe diverse Dinge ausprobiert mit @XMLElement und -Attribute, dann hab ich das wie man sieht als String ausgegeben. Da werden die Nullwerte halt auch als Nullwerte angezeigt.
@Column(name="columnName") habe ich auch bei allen schon ausprobiert.
Der Primärschlüssel hat übrigens mit @EmbeddedId nicht funtioniert, also habe ich jetzt die andere Variante ausprobiert und siehe da! Der PK funktioniert! Keine Ahnung warum.
Ich habe Long schon in BigInteger (Ist BigInt bzw int8 in der Datenbank) und Bid Decimal umgeschrieben. Da String funktionieren, Long aber nicht dachte ich dass es am mapping des Datentyps liegt. Date wird aber auch als NullWert angezeigt.
Nachdem ich jetzt gefühlt drei Tage alles Erdenkliche ausprobiert habe was ich so in den weiten des Internets gefunden habe bin ich mit meinem Latein am Ende :/

Wenn jemand weiß wie man den Datentyp tsrange von PostgreSQL richtig mappt da wäre ich auch sehr dankbar wenn mir da jemand weiter helfen könnte.

Vielen Dank schonmal im vorraus
Asperah
 

mihe7

Top Contributor
Was zumindest schon einmal auffällt: zweimal @Id darf nicht sein. Ansonsten würde ich mal in der persistence.xml das SQL-Logging aktivieren, dann weißt Du mehr. EDIT: die persistence.xml köntest Du auch noch posten.
 

Asperah

Mitglied
Also der Primärschlüssel ist ein Composite Primary Key und das hab ich nach dem hier gemacht:


Bisher funktionierts mit dem PK auch.

Hier ist die persistence.xml:
Java:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="sistestdb" transaction-type="JTA">
    <jta-data-source>jdbc/sistestdb</jta-data-source>
        <class>model.Test</class>
        <class>model.TestPK</class>
    </persistence-unit>
</persistence>
 

Asperah

Mitglied
Dann solltest Du einiges an Infos bekommen.
Oh, das ist super, danke, da kommen wirklich mehr Infos.

Ich fürchte ich muss am Wochenende das ganze mal Zuhause reproduzieren ohne Firmandaten. Ich bin nämlich grad im Praktikum und hab die Namen von Tabellen und Co alle durch "Test" etc. ersetzt in der Hoffnung dass das schon reicht um erkennen zu können was ich falsch gemacht hab 😅 Dann trau ich mich auch Logs zu posten.

Danke übrigens für die schnellen Antworten :)
 

Asperah

Mitglied
Yeah, kleines Update zum Feierabend: Es lag am Gültigkeitszeitraum. Der hat auch ne Exeption geschmissen aber danach alles brav angezeigt, halt nur die Hälfte mit NullWerten (Die Werte die er nach Gültigkeitszeitraum lesen sollte hat er wohl nicht mehr gelesen). Ich hätte nicht gedacht dass er dann trotzdem ne Ausgabe macht :)
Nachdem ich jetzt den Gültigkeitswert erstmal rauskommentiert habe funktioniert es.

Jetzt ist aber immernoch die Frage wie ich die tsrange richtig mappe. Im Notfall könnte ich das ganze in zwei Spalten aufteilen mit start und end timestamp, aber ich würde total gerne die tsrange-Möglichkeiten von Postgresql benutzen.
 

mrBrown

Super-Moderator
Mitarbeiter
Jetzt ist aber immernoch die Frage wie ich die tsrange richtig mappe. Im Notfall könnte ich das ganze in zwei Spalten aufteilen mit start und end timestamp, aber ich würde total gerne die tsrange-Möglichkeiten von Postgresql benutzen.
Das wirst du vermutlich mit nem eigenem Typ und Attribute Convertern (oder was Eclipselink-eigenem) lösen müssen. Direkt lassen sich ranges nicht mit JPA mappen, für Hibernate gäb's schon entsprechende fertige Typen, für Eclipse-Link allerdings soweit ich weiß nicht.
 

Asperah

Mitglied
Das wirst du vermutlich mit nem eigenem Typ und Attribute Convertern (oder was Eclipselink-eigenem) lösen müssen. Direkt lassen sich ranges nicht mit JPA mappen, für Hibernate gäb's schon entsprechende fertige Typen, für Eclipse-Link allerdings soweit ich weiß nicht.
Oh ich hatte es befürchtet. Danke für den Tipp mit den Attribute Convertern, ich hatte die zwar schon ins Auge gefasst aber 100% sicher war ich mir nicht ob das das richtige ist. Ich werd mich da mal reinlesen und dann hoffe ich dass alles funktioniert. Vielen dank auf jeden Fall an euch für die schnelle Hilfe.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D NativeQuery - Hibernate - PostgreSQL Data Tier 2
S JPA Hibernate Search & EclipseLink (oder OpenJPA) Data Tier 0
R JPA Probleme mit Wechsel von EclipseLink auf Hibernate Data Tier 4
A EclipseLink JPA - ManyToMany und Select Abfrage Data Tier 8
J EclipseLink EntityManager Data Tier 4
F JPA + EclipseLink rekursive Beziehung löschen Data Tier 2
N [EclipseLink] Best Practise zur Generierung von Entities aus Tabellen Data Tier 28
M EclipseLink 2 MetaModel/Canonical Model Generation Data Tier 3
C EclipseLink in eine JavaEE Tomcat Anwendung einbinden Data Tier 7
M eclipselink Data Tier 2
T JPA/Eclipselink: DB Schema anlegen? Data Tier 9
G JPA/ Eclipselink: (Alte) Kopie einer Entity? Data Tier 6
D jpa/eclipselink setMaxResults() funktioniert nicht mit MySql?! Data Tier 9
OnDemand OneToMany Composite Key Mapping Data Tier 18
G Hibernate Collection Mapping - Fehler beim Updaten der DB Data Tier 0
P Hibernate Mapping - Nur eine Spalte per Join aus anderer Tabelle holen Data Tier 5
R mapping-file für hibernate zum Überschreiben der Annotationen Data Tier 7
M Problem mit @Temporal Mapping und SQL Server Data Tier 3
H Hibernate - Mapping für Enumeration Data Tier 1
S (Hibernate) Mapping einer Datenbanktabelle mit mehreren Fremdschlüssel Data Tier 7
Kessi Hibernate Mapping-File vs. Annotations Data Tier 4
M Hibernate Mapping mal anders Data Tier 2
N Hibernate boolean mapping Data Tier 7
M JPA: Mapping von bestehender DB Data Tier 2
byte Hibernate: duplicate property mapping Data Tier 3
N Mapping einer 1:n in Hibernate Data Tier 11
F OR-Mapping Data Tier 4

Ähnliche Java Themen


Oben