我在服务中尝试创建Foo_x_Bar_Status的新记录的3个表Foo,Bar和Foo_x_Bar_Status。我先获取Foo的托管对象和Bar的托管对象,然后即时创建FooBarStatus的新对象并在其上设置先前获取的Foo和Bar对象。然后,我试图保留我新创建的FooBarStatus wirh entityManager.merge()
(它需要合并,因为我需要返回FooBarStatus受管对象而不再次搜索它),但是此合并失败并显示消息:java.sql.SQLException: - ORA-01000: maximum open cursors exceeded
,如何我可以解决这个问题吗?
P.S。我知道我只能从Foo和Bar中删除收藏夹,并且可以通过专用服务访问,但是对我来说,建立这种双向关系至关重要
Foo:
@Entity(name = "Foo")
@Table(name = "FOO")
public class Foo implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FOO_SEQ")
private Long id;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST, mappedBy = "foo", orphanRemoval = true)
private Set<FooBarStatus> fooBarStatus;
}
栏:
@Entity(name = "Bar")
@Table(name = "BAR")
public class BAR implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "BAR_SEQ")
private Long id;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST, mappedBy = "bar", orphanRemoval = true)
private Set<FooBarStatus> fooBarStatus;
}
FooBarStatus:
@Entity(name = "FooBarStatus")
@Table(name = "Foo_x_Bar_Status")
public class FooBarStatus implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FOO_BAR_STATUS_SEQ")
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "FOO_ID", nullable = false)
private Foo foo;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "BAR_ID", nullable = false)
private Bar bar;
服务
@Service
public class FooBarStatusServiceImpl implements FooBarStatus {
@Autowired
private FooRepository fooRepository;
@Autowired
private BarRepository barRepository;
@Autowired
private FooBarStatusReposiotry fooBarStatusReposiotry;
@Override
public FooBarStatus createFooBarStatus(Foo foo, Bar bar) {
//make foo nd bar managed
foo = fooRepository.createFoo(foo);
bar = barRepository.createBar(bar);
FooBarStatus fooBarStatus = new FooBarStatus();
fooBarStatus.setFoo(foo);
fooBarStatus.setBar(bar);
return fooBarStatusReposiotry.createFooBarStatus(fooBarStatus);
}
}
FooBarStatusReposioty:
@Repository
public class FooBarStatusReposiotyImpl implements FooBarStatusReposioty {
@PersistenceContext
public EntityManager entityManager;
@Override
public FooBarStatus createFooBarStatus(FooarStatus fooBarStatus){
return entityManager.merge(fooBarStatus);
}
}
Stacktrace:
2018-11-28 16:43:02 ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet] with root cause
java.sql.SQLException: ORA-01000: maximum open cursors exceeded
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:774)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:925)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1111)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:4845)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1501)
at sun.reflect.GeneratedMethodAccessor154.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
at com.sun.proxy.$Proxy119.executeQuery(Unknown Source)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.getResultSet(AbstractLoadPlanBasedLoader.java:434)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(AbstractLoadPlanBasedLoader.java:186)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:121)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:88)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1991)
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:570)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:252)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:566)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:135)
at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:430)
at com.iwork.server.defautmodel.User.hashCode(User.java:20)
at com.iwork.server.defautmodel.UserNotification.hashCode(UserNotification.java:11)
at java.util.HashMap.hash(HashMap.java:339)
at java.util.HashMap.put(HashMap.java:612)
at java.util.HashSet.add(HashSet.java:220)
at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
at org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:327)
at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:234)
at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:221)
at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:194)
at org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl.endLoading(CollectionReferenceInitializerImpl.java:154)
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishLoadingCollections(AbstractRowReader.java:249)
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:212)
at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:133)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:88)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1991)
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:570)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:252)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:566)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:135)
at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:430)
at com.application.server.defautmodel.Bar.hashCode(Bar.java:20)
at com.application.server.defautmodel.Foo.hashCode(Foo.java:11)
at java.util.HashMap.hash(HashMap.java:339)
at java.util.HashMap.put(HashMap.java:612)
at java.util.HashSet.add(HashSet.java:220)
at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
stacktrace更长,但看起来像是循环。
Foo.java:11和Bar.java:20指向龙目岛的@Data
注释
答案 0 :(得分:0)
此错误是由连接,语句和结果集保持打开状态引起的。例子
Connection with = getConnection();
PreparedStatement ps = con.prepareStatement
ResultSet rs = ps.executeQuery ();
因此,您只需关闭
rs.close ();
ps.close ();
con.close ();
选项是使用try {}抓住(e){}最终{}并在finally中关闭
答案 1 :(得分:0)
@Chris在评论中建议,根本原因是使用@Data
批注生成了HashCode计算方法,并且由于Foo,Bar和FooBarStatus具有具有双向关系的惰性初始化属性,因此哈希计算试图获取数据并无限向后退去。由于所有Foo,Bar和FooBarStatus的ID都是唯一的,因此不必在哈希计算中包括加入的属性。因此,根据https://projectlombok.org/features/EqualsAndHashCode,我向双向懒惰初始化属性添加了@ EqualsAndHashCode.Exclude,该属性从哈希计算中排除了该属性。下面的示例:
@Entity(name = "Foo")
@Table(name = "FOO")
public class Foo implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FOO_SEQ")
private Long id;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST, mappedBy = "foo", orphanRemoval = true)
@EqualsAndHashCode.Exclude
private Set<FooBarStatus> fooBarStatus;
}