我有两个Java类:
第一个类Class1如下所示:
@Entity
@Table(catalog = "mydb", schema = "dbo", name = "[myTable1]")
@Getter
@Setter
@Builder
@ToString(onlyExplicitlyIncluded = true)
@AllArgsConstructor
@NoArgsConstructor
public class Class1 {
@Id
@Column(name = "ID")
@GeneratedValue(generator = "myGen")
@GenericGenerator(name = "myGen",
strategy = "Y.X.z.generator.MyGen")
private Long id;
@Column(name = "TEXT")
private String text;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "ID")
private Class2 class2;
第二个类Class2如下所示
@Entity
@Table(catalog = "mydb", schema = "dbo", name = "[myTable2]")
@Getter
@Setter
@Builder
@ToString(onlyExplicitlyIncluded = true)
@AllArgsConstructor
@NoArgsConstructor
public class Class2 {
@Id
@Column(name = "ID")
@GeneratedValue(generator = "myGen")
@GenericGenerator(name = "myGen",
strategy = "de.svg.releasenotes.generator.MyGen")
private Long id;
@Column(name = "TEXT")
private String text;
正如您所看到的,类1与类2之间存在ManyToOne关联。类1和类2使用相同的GenericGenerator(Y.X.z.generator.MyGen)。
发生器如下所示:
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;
import java.io.Serializable;
import java.util.stream.Stream;
public class MyGen implements IdentifierGenerator {
@Override
public Serializable generate(
SharedSessionContractImplementor session, Object obj)
throws HibernateException {
String query = String.format("select %s from %s",
session.getEntityPersister(obj.getClass().getName(), obj)
.getIdentifierPropertyName(),
obj.getClass().getSimpleName());
Stream<Long> ids = session.createQuery(query).stream();
Long max = ids.max(Long::compare).orElse(0L);
return max + 1;
}
}
生成器make从DB.TableX中检索最大ID并将其递增1。
当我呼叫POST端点时,收到下列错误:
2022-11-15 15:27:26.214 ERROR 276510 --- [io-13778-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause
java.lang.StackOverflowError: null
at org.apache.logging.slf4j.SLF4JLogger.isEnabledFor(SLF4JLogger.java:213) ~[log4j-to-slf4j-2.17.2.jar:2.17.2]
at org.apache.logging.slf4j.SLF4JLogger.isEnabled(SLF4JLogger.java:121) ~[log4j-to-slf4j-2.17.2.jar:2.17.2]
at org.apache.logging.log4j.spi.AbstractLogger.isEnabled(AbstractLogger.java:1513) ~[log4j-api-2.17.2.jar:2.17.2]
at org.jboss.logging.Log4j2Logger.isEnabled(Log4j2Logger.java:46) ~[jboss-logging-3.4.3.Final.jar:3.4.3.Final]
at org.jboss.logging.Logger.isTraceEnabled(Logger.java:98) ~[jboss-logging-3.4.3.Final.jar:3.4.3.Final]
at org.jboss.logging.DelegatingBasicLogger.isTraceEnabled(DelegatingBasicLogger.java:54) ~[jboss-logging-3.4.3.Final.jar:3.4.3.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:86) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:159) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:149) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:82) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:50) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1372) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1452) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at Y.X.z.generator.MyGen.generate(MyGen.java:25) ~[classes/:na]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:115) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:801) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.engine.spi.CascadingActions$8.cascade(CascadingActions.java:341) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:510) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:434) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:220) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:153) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:159) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:149) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:82) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:50) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1372) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1452) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at Y.X.z.generator.MyGen.generate(MyGen.java:25) ~[classes/:na]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:115) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:801) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.engine.spi.CascadingActions$8.cascade(CascadingActions.java:341) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:510) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:434) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:220) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:153) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:159) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:149) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:82) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:50) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1372) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1452) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617) ~[hibernate-core-5.6.12.Final.jar:5.6.12.Final]
...
这表明MyGen有一个StackOverflowError。
有什么办法可以解决我的问题吗?
谢谢你,谢谢你
1条答案
按热度按时间63lcw9qa1#
从堆栈跟踪看,似乎您可能在休眠中发现了一个bug,但很难分辨。
好消息是,如果我正确理解了您要做的事情,您就不需要自定义生成器,这意味着您应该能够解决您的问题。
您可以使用
SEQUENCE
生成策略为实体实现单调递增的id:第一个