Как произвести извлечение JSON формата из PostgreSQL правильным образом через NetBeans?

112
15 марта 2022, 03:20

Я использую EclipseLink JPA 2.1. в NetBeans.

Создал табличку в БД PostgreSQL:

CREATE TABLE public.test_json (
    id serial NOT NULL,
    json_data json NOT NULL,
    CONSTRAINT test_json_pkey PRIMARY KEY (id)
);

В NetBeans выполнил команду "Entity Classes From DataBase", и попытался произвести отражение табличного представления из БД на мой Entity класс.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication6;
import java.io.Serializable;
import java.sql.Clob;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
/**
 *
 * @author ramze
 */
@Entity
@Table(name = "test_geometry")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "TestGeometry.findAll", query = "SELECT t FROM TestGeometry t")
    , @NamedQuery(name = "TestGeometry.findById", query = "SELECT t FROM TestGeometry t WHERE t.id = :id")})
public class TestGeometry implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Lob
    @Column(name = "geom")
    private Object geom;
    public TestGeometry() {
    }
    public TestGeometry(Integer id) {
        this.id = id;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Object getGeom() {
        return geom;
    }
    public void setGeom(Serializable geom) {
        this.geom = geom;
    }
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }
    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof TestGeometry)) {
            return false;
        }
        TestGeometry other = (TestGeometry) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }
    @Override
    public String toString() {
        return "javaapplication6.TestGeometry[ id=" + id + " ]";
    }
}

После того как это было успешно выполнено, я попытался присоединиться к моей БД и извлечь оттуда информацию:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("Name_of_my_connection");

где Name_of_my_connection = 'JavaApplication5PU'

Но Java не понимает JSON формат и выдала мне следующую ошибку.

debug:
Exception in thread "main" Local Exception Stack: 
Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: sun.misc.Launcher$AppClassLoader@18b4aac2
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [JavaApplication5PU] failed.
Internal Exception: Exception [EclipseLink-7164] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The type [class java.lang.Object] for the attribute [jsonData] on the entity class [class javaapplication5.TestJson] is not a valid type for a lob mapping. For a lob of type BLOB, the attribute must be defined as a java.sql.Blob, byte[], Byte[] or a Serializable type. For a lob of type CLOB, the attribute must be defined as a java.sql.Clob, char[], Character[] or String type.
    at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:127)
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:107)
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:177)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at javaapplication5.JavaApplication5.main(JavaApplication5.java:23)
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [JavaApplication5PU] failed.
Internal Exception: Exception [EclipseLink-7164] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The type [class java.lang.Object] for the attribute [jsonData] on the entity class [class javaapplication5.TestJson] is not a valid type for a lob mapping. For a lob of type BLOB, the attribute must be defined as a java.sql.Blob, byte[], Byte[] or a Serializable type. For a lob of type CLOB, the attribute must be defined as a java.sql.Clob, char[], Character[] or String type.
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createPredeployFailedPersistenceException(EntityManagerSetupImpl.java:1954)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1945)
    at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.callPredeploy(JPAInitializer.java:98)
    at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:96)
    ... 4 more
Caused by: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [JavaApplication5PU] failed.
Internal Exception: Exception [EclipseLink-7164] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The type [class java.lang.Object] for the attribute [jsonData] on the entity class [class javaapplication5.TestJson] is not a valid type for a lob mapping. For a lob of type BLOB, the attribute must be defined as a java.sql.Blob, byte[], Byte[] or a Serializable type. For a lob of type CLOB, the attribute must be defined as a java.sql.Clob, char[], Character[] or String type.
    at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:230)
    ... 8 more
Caused by: Exception [EclipseLink-7164] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The type [class java.lang.Object] for the attribute [jsonData] on the entity class [class javaapplication5.TestJson] is not a valid type for a lob mapping. For a lob of type BLOB, the attribute must be defined as a java.sql.Blob, byte[], Byte[] or a Serializable type. For a lob of type CLOB, the attribute must be defined as a java.sql.Clob, char[], Character[] or String type.
    at org.eclipse.persistence.exceptions.ValidationException.invalidTypeForLOBAttribute(ValidationException.java:1132)
    at org.eclipse.persistence.internal.jpa.metadata.converters.LobMetadata.process(LobMetadata.java:124)
    at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor.processLob(MappingAccessor.java:1707)
    at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicAccessor.processLob(BasicAccessor.java:524)
    at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor.processMappingConverter(MappingAccessor.java:1771)
    at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor.processMappingValueConverter(MappingAccessor.java:1796)
    at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicAccessor.process(BasicAccessor.java:419)
    at org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor.processMappingAccessors(MetadataDescriptor.java:1536)
    at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor.processMappingAccessors(ClassAccessor.java:1648)
    at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.processMappingAccessors(EntityAccessor.java:1234)
    at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.process(EntityAccessor.java:697)
    at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage2(MetadataProject.java:1793)
    at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:576)
    at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:585)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1869)
    ... 6 more
C:\Users\ramze\AppData\Local\NetBeans\Cache\8.2\executor-snippets\debug.xml:83: Java returned: 1
BUILD FAILED (total time: 4 seconds)

Подскажите, пожалуйста, что нужно сделать, чтобы исправить эту ошибку? Как правильным образом отразить табличное представление, где один из столбцов представляет собой JSON формат???

Answer 1

Короче, я сам решил это:

1) Вот моя таблица в базе:

2) В автоматически сформированном ORM-классе TestJson:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication5;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
/**
 *
 * @author ramze
 */
@Entity
@Table(name = "test_json")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "TestJson.findAll", query = "SELECT t FROM TestJson t")
    , @NamedQuery(name = "TestJson.findById", query = "SELECT t FROM TestJson t WHERE t.id = :id")})
public class TestJson implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Lob
    @Column(name = "json_data")
    private Object jsonData;
    public TestJson() {
    }
    public TestJson(Integer id) {
        this.id = id;
    }
    public TestJson(Integer id, Object jsonData) {
        this.id = id;
        this.jsonData = jsonData;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Object getJsonData() {
        return jsonData;
    }
    public void setJsonData(Object jsonData) {
        this.jsonData = jsonData;
    }
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }
    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof TestJson)) {
            return false;
        }
        TestJson other = (TestJson) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }
    @Override
    public String toString() {
        return "javaapplication5.TestJson[ id=" + id + " ]";
    }
}

Изменил

@Lob
@Column(name = "json_data")
private Object jsonData;
public Object getJsonData() {
    return jsonData;
}

на

@Lob
@Column(name = "json_data")
private String jsonData;
public String getJsonData() {
    return jsonData;
}

Выполнил вот этот код:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("JavaApplication5PU");
EntityManager em = emf.createEntityManager();
TestJson test_json = em.createNamedQuery("TestJson.findAll", TestJson.class).getSingleResult();

И в переменной test_json получил адекватный строковый json:

READ ALSO
Как работает многопоточность java [дубликат]

Как работает многопоточность java [дубликат]

Объясните пожалуйста буквально на пальцах, простыми словами, как работает многопоточность в javaЕсть вопросы на которые я не могу найти ТОЧНЫЙ...

116
Как преобразовать одномерный массив в дву-мерный

Как преобразовать одномерный массив в дву-мерный

Допустим у меня есть одномерный массив

95
Как заблокировать все кнопки при нажатии одной из них?

Как заблокировать все кнопки при нажатии одной из них?

Мне нужно блокировать кнопки после нажатия любой из них на 5 секундКак я могу это сделать? Именно на 5 вроде через Thread

95