SQLGrammerException: не удалось получить ResultSet для em.persist () - PullRequest
1 голос
/ 27 июня 2019

Я изучаю JPA и хочу создать новую запись в моей таблице с JPA, каскадно добавляя дочерние элементы.

Код работает нормально, пока я не хочу сохранить новую запись. Сначала я думал, что это ошибка отображения, но я не нашел ничего плохого в структуре моей базы данных (или я галлюцинирую до н.э. тепла)

Так почему я не могу упорствовать?

Клиент

package client;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import dao.GeneralDAO;
import entity.Artemis;
import entity.Welt;

public class client {

    public static void main(String[] args) {

        GeneralDAO artemis = new GeneralDAO("JPA_REAL", Artemis.class);
        System.out.println(artemis);
        GeneralDAO welt = new GeneralDAO("JPA_REAL", Welt.class);
        System.out.println(welt);

        System.out.println("Artemis Liste: " + artemis.list());
        System.out.println("Artems by PK: " + artemis.findByPrimaryKey(1));
        System.out.println("Welt by PK: " + welt.findByPrimaryKey(2));
        System.out.println("Welt Liste: " + welt.list());

        Collection<?> objs;
        Collection<?> objs1;

        objs = artemis.list();
        objs1 = welt.list();

        Artemis art1 = null;

        System.out.println("Field: " + artemis.getField());


  Artemis a2 = new Artemis("Zeus");

          Artemis a3 = new Artemis();

          a3.setName("Jupiter");

          List<Welt> a2_welt = new ArrayList<Welt>();

          a2_welt.add(new Welt("Earth"));

          a2_welt.add(new Welt("Mars"));

          a2.setWelts(a2_welt);

          artemis.store(a2);





        for (Object s : objs) {
            System.out.println("s=" + ((Artemis) s).getName());
            System.out.println("id=" + ((Artemis) s).getId());
            for (Welt w : ((Artemis) s).getWelts())
                System.out.println("w=" + w.getName());
        }

        artemis.close();
        welt.close();
    }
}

DAO

package dao;

import java.lang.reflect.Field;
import java.util.Collection;

import javax.persistence.*;



public class GeneralDAO {

    EntityManager em;
    private Field[] field;
    private int primaryKeyIndex;



    private Class <?> clazz;

    public GeneralDAO(String PersistenceUnit, Class <?> clazz) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory(PersistenceUnit);
    em = emf.createEntityManager();
    this.clazz=clazz;   
    }


    public Field[] getField() {
        field = clazz.getDeclaredFields();

        return field;
    }

    public Collection <?> list(){
        String Statement = "Select q from " + clazz.getSimpleName() + " q";
        return em.createQuery(Statement).getResultList();
    }

    public Object findByPrimaryKey(int pk) {
        Object returnObject = em.find(clazz, pk);
        return returnObject;
    }

    public void store(Object s) {
        EntityTransaction ta = em.getTransaction();
        ta.begin();
        em.persist(s);
        ta.commit();

    }

    public void remove(int pk) {
        Object returnObject = em.find(clazz, pk);
        EntityTransaction ta = em.getTransaction();
        ta.begin();
        em.remove(returnObject);
        ta.commit();
    }

    public void close() {
        em.clear();
        em.close();


    }

    public void refresh(Object s) {
        em.refresh(s);
    }
    /*
     * public Collection <?> executeQuery() { System.out.println("Query Start");
     * Query Query = em.createQuery("Select e from Artemis e join e.id t");
     * List<Artemis> resultList = Query.getResultList(); for (Artemis s: resultList)
     * System.out.println(Artemis.getName() "+" Artemis.getWorld()); }
     */

}

Welt Entity

package entity;

import java.io.Serializable;
import javax.persistence.*;


/**
 * The persistent class for the WELT database table.
 * 
 */
@Entity
@NamedQuery(name="Welt.findAll", query="SELECT w FROM Welt w")
public class Welt implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    @Column(name="id")
    int id;

    @Column(name="name")
    private String name;

    //bi-directional many-to-one association to Artemis
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="fk_artemis")
    private Artemis artemis;

    public Welt() {

    }

    public Welt(int i, String string, int j) {

    }

    public Welt(int i, String string) {
    }

    public Welt(String string) {
    }

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

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

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Artemis getArtemis() {
        return this.artemis;
    }

    public void setArtemis(Artemis artemis) {
        this.artemis = artemis;
    }

}

Артемида Сущность

package entity;

import java.io.Serializable;
import javax.persistence.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


/**
 * The persistent class for the ARTEMIS database table.
 * 
 */
@Entity
@NamedQuery(name="Artemis.findAll", query="SELECT a FROM Artemis a")
public class Artemis implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    @Column(name="id")
    private int id;

    @Column(name="name")
    private String name;

    //bi-directional many-to-one association to Welt
    @OneToMany(mappedBy="artemis", fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
    private List<Welt> welts = new ArrayList<Welt>();

    public Artemis() {
    }

    public Artemis(int id, String name) {
        this.id=id;
        this.name=name;
    }

    public Artemis(String name) {
        this.name=name;
    }

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

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

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Welt> getWelts() {
        return welts;
    }

    public Collection<Welt> getWeltName() {
        return welts;
    }

    public void setWelts(List<Welt> welts) {
        this.welts = welts;
    }

    public Welt addWelt(Welt welt) {
        getWelts().add(welt);
        welt.setArtemis(this);

        return welt;
    }

    public Welt removeWelt(Welt welt) {
        getWelts().remove(welt);
        welt.setArtemis(null);

        return welt;
    }

    @Override
    public String toString() {
        return "Artemis [id=" + id + ", name=" + name + ", welts=" + welts + "]";
    }


}

StackTrace

//other console output
    dao.GeneralDAO@77c1e611
    Artemis Liste: []
    Artems by PK: null
    Welt by PK: null
    Welt Liste: []
    Field: [Ljava.lang.reflect.Field;@17fede14
    Juni 27, 2019 9:06:16 NACHM. org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
    WARN: SQL Error: 2289, SQLState: 42000
    Juni 27, 2019 9:06:16 NACHM. org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
    ERROR: ORA-02289: sequence does not exist

    Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
        at dao.GeneralDAO.store(GeneralDAO.java:46)
        at client.client.main(client.java:77)
    Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
        at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63)
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:69)
        at org.hibernate.id.enhanced.SequenceStructure$1.getNextValue(SequenceStructure.java:95)
        at org.hibernate.id.enhanced.NoopOptimizer.generate(NoopOptimizer.java:40)
        at org.hibernate.id.enhanced.SequenceStyleGenerator.generate(SequenceStyleGenerator.java:519)
        at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:119)
        at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:192)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:62)
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:804)
        ... 3 more
    Caused by: java.sql.SQLSyntaxErrorException: ORA-02289: sequence does not exist

        at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:494)
        at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:446)
        at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1052)
        at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:537)
        at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:255)
        at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:610)
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:253)
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:86)
        at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:765)
        at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:921)
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1099)
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3640)
        at oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedStatement.java:1384)
        at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3687)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1165)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60)
        ... 11 more
    Caused by: Error : 2289, Position : 7, Sql = select hibernate_sequence.nextval from dual, OriginalSql = select hibernate_sequence.nextval from dual, Error Msg = ORA-02289: sequence does not exist

        at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:498)
        ... 26 more

Ответы [ 2 ]

0 голосов
/ 28 июня 2019

Причина, по которой произошел сбой, заключалась в том, что в моей базе данных не было последовательности, используемой в @Generated Value

Примечание) это будет работать.

@ GeneratedValue использует стандарт SEQUENCE в Oracle, но я его не генерировал.Я сделал две последовательности с create sequence ... для каждой таблицы и изменил @GeneratedValue с типом, именем последовательности и добавил @ SequenceGenerator.

Мне пришлось отбросить последовательность, которая была на месте с drop sequence dual, и автоматическисработало генерирование ключей, постоянных и внешних ключей.

0 голосов
/ 28 июня 2019

Аннотация @JoinColumn указывает имя столбца, используемого в качестве внешнего ключа для целевого объекта.

В приведенном выше классе Welt имя столбца объединения установлено в "fk_artemis".

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="fk_artemis")
private Artemis artemis;

Итак, эта ошибка обычно возникает, если внешний ключ в таблице Product назван не так, как указано в классе, а в данном случае: "fk_artemis".

Вам необходимо изменить либо имя столбца в таблице, либо имя, которое вы используете в @JoinColumn, чтобы они совпадали.

Есть и другие причины дляэта ошибка.Но, в основном, это связано с несовпадением имен.

...