我正在学习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()); }
*/
}
贴边实体
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;
}
}
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
答案 0 :(得分:0)
@JoinColumn批注指定用作目标实体上的外键的列的名称。
在上面的Welt类上,联接列的名称设置为“ fk_artemis”。
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="fk_artemis")
private Artemis artemis;
因此,如果Product表上的外键被命名为类中给定的以外的其他名称,并且在这种情况下为“ fk_artemis”,则通常会出现此错误。
您需要更改表上的列名称或@JoinColumn中使用的名称,以使它们匹配。
此错误的原因更多。但是,主要是由于名称不匹配。
答案 1 :(得分:0)
失败的原因是我的数据库没有@Generated Value中使用的序列
旁注:如果我要删除@GeneratedValue并输入以下内容 主键(1,“无论如何”)都可以。
@GeneratedValue在Oracle中按标准使用SEQUENCE,但是我没有生成一个。我为每个表用create sequence ...
制作了两个序列,并用类型,序列名称和@GeneratedValue修改了序列,并添加了@SequenceGenerator。
我不得不删除一个drop sequence dual
适当的序列,并且自动生成密钥,持久化和外键起作用。