我对Hibernate和JPA存储库的实现有问题。
我得到了关于错误:
"发生异常后不要刷新会话"
这是从第节开始的-
消息表:
@Entity
@Table(name="message")
public class Message {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "type")
private MessageType type;
@Column(name = "date")
private Timestamp date;
@Column(name = "message")
private String message;
@ManyToOne(cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH})
@JoinColumn(name="user_id")
private User User;
//constructor, empty constructor, getter & setter
}
用户表:
@Entity
@Table(name = "user")
public class User {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "city")
private String city;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "user",
cascade = {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH})
private List<Message> message;
//constructor, empty constructor, getter & setter
}
服务:
@Service
@Transactional
public class MessageUserDataService implements MessageUserService {
public void saveToDatabase(String data, String type, String message) {
long userId;
if (data.containsKey(userCode)) {
userId = findUserId(userCode);
}
MessageData messageData = new MessageData();
User user = UserSystemService.findByUserId(id);
messageData.setUser(user);
messageData.setType(type);
messageData.setMessage(message);
messageDataService.save(messageData);
}
public long findUserId(Long id) {
try {
User user = UserSystemService.findByUserId(id);
return user.getId();
} catch (Exception e) {
log("findUserId->id: " + id);
throw e;
}
}
可能这就是问题所在——这是一个例外。会议仍然开放。当然,我在服务中有事务注释。
以及执行日志:
29.07.2019 21:43:12org.hibernate.AssertionFailure: null id in com.test.app.model.Message entry (don't flush the Session after an exception occurs)
29.07.2019 21:43:12 at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:60)
29.07.2019 21:43:12 at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:175)
29.07.2019 21:43:12 at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:135)
29.07.2019 21:43:12 at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:216)
29.07.2019 21:43:12 at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:85)
29.07.2019 21:43:12 at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:44)
29.07.2019 21:43:12 at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1398)
29.07.2019 21:43:12 at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1483)
29.07.2019 21:43:12 at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445)
29.07.2019 21:43:12 at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414)
29.07.2019 21:43:12 at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1463)
29.07.2019 21:43:12 at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:214)
29.07.2019 21:43:12 at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:91)
29.07.2019 21:43:12 at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:136)
29.07.2019 21:43:12 at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:125)
29.07.2019 21:43:12 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:590)
29.07.2019 21:43:12 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:578)
29.07.2019 21:43:12 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
29.07.2019 21:43:12 at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
29.07.2019 21:43:12 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
29.07.2019 21:43:12 at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
29.07.2019 21:43:12 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
29.07.2019 21:43:12 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
29.07.2019 21:43:12 at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
29.07.2019 21:43:12 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
29.07.2019 21:43:12 at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
29.07.2019 21:43:12 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
29.07.2019 21:43:12 at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
29.07.2019 21:43:12 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
29.07.2019 21:43:12 at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
29.07.2019 21:43:12 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
29.07.2019 21:43:12 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
29.07.2019 21:43:12 at com.test.app.model.service.UserService.findUserId(UserService.java:14)
下面是您问题中的代码:
public long findUserId(Long id) {
try {
User user = UserSystemService.findByUserId(id);
return user.getId();
} catch (Exception e) {
log("findUserId->id: " + id);
throw e;
}
}
您从数据库中获取记录并将其保存在实体中。然后,在catch
块中,记录错误并重新引发异常。到目前为止还不错。但是,您正在刷新会话或在某处提交事务。你没有在问题中详细提到你的工作单元策略。
问题是,您试图刷新会话或在异常后提交事务。你不应该那样做。异常之后,您应该丢弃会话实例。
为什么不在Hibernate异常后刷新?
工作单元是一个非常复杂的系统。它会跟踪所有加载实体的更改。Hibernate在保持实体的内存拷贝与底层RDBMS一致方面做得很好。刷新
(或其他自动刷新方式)将使用内存中的更改更新RDBMS。当抛出Hibernate异常时,不能保证内存中的状态不再处于一致状态。这就是为什么Hibernate建议关闭会话,从头开始。
你在问题中提到的例外:
org.hibernate.AssertionFailure:com.test.app.model.Message条目中的null id(发生异常后不要刷新会话)
这并不是真正的例外。在此之前发生过真正的例外。您正在catch
块中记录异常。如果发生异常,catch
块应该关闭会话——如果没有提交,它也会回滚事务。
如果出现异常,您应该关闭会话。由于没有太多关于如何在代码中实现会话的信息,以下只是一个示例:
catch (Exception e) {
log("findUserId->id: " + id);
session.close();//<--close the session. This will also rollback the transaction if not committed
throw e;
}
但是,正如我上面所说,这不是真正的解决方案。代码的另一部分出现错误。你必须诊断并修复它。我通常把放在会话中。flush()
在我怀疑的代码块之后;这样,就很容易找到引发真正异常的确切代码行。
最有可能的是,在调用findUserId()
方法之前,您已经在其他地方抑制了一个异常。当您调用findUserId()
时,会报告错误,因为在随后的调用中,Hibernate决定是时候对com.test.app.model.Message
实体进行自动刷新了。
你应该考虑复习你的会话维护策略。如果是一个会话绑定到请求线程的常见web场景,而不是一个保持会话打开数小时的独立应用程序,那么修复将有所不同。
我试图在一个catch块中执行一些更新操作。冬眠例外ConstraintViolationException抛出如下 我正在使用Hibernate 4.3.6 这是我的UserRegistrationRequest实体 这是我的UserSecurityQuestions实体 尝试在catch块中执行更新时,我遇到以下错误 如果我抓住异常而不是约束违反异常看到下面的错误 有人能帮帮我吗,有没有更好的
编辑:得到一个-1,你能解释一下为什么吗?我搜索了重复项,但没有找到任何重复项。 为我刚刚遇到的问题发布Q/a: 例外情况: org.hibernate.AssertionFailure: null id in xyz (在发生异常后不要刷新会话)
我设置了一个非常基本的Grails 3 web应用程序,使用jdbc连接到PostgreSQL数据库。下面您可以找到< code>Cluster域类和专用服务的代码。 碰巧用同一个< code>slug参数调用了< code>createCluster方法两次: 导致以下异常 我以为违反一约束会被方法拦截,但显然我错了。好吧,所以我添加了一个try/catch,但它基本上没有效果,异常没有被包装,
我有一个hibernate和JSF2应用程序进入部署服务器,突然抛出一个org。冬眠AssertionFailure:异常中的空id。我将立即提供堆栈跟踪和代码,但首先有四个重要问题: > 这只发生在部署服务器(Jboss)上 研究这一点,人们在尝试插入对象时似乎会出现这种错误。但是当我做一个简单的查询时,我得到了错误。(实际上,各种不同的查询,因为错误会随机出现在多个页面上。) 错误只会偶尔出现
问题内容: 当取消注释时,我们将在第二种方法中获得en异常- 当作者。 为什么会这样呢? 问题答案: 问题似乎是Hibernate引发了一个异常(因此当前事务无效),但是随后您尝试在该会话中继续执行更多操作。 正确的方法是将您使用的测试分为2部分,一部分测试空作者,另一部分测试有效作者。 在生产代码(例如控制器)上,您需要重新启动操作(关闭事务,重新启动流程)才能继续。但是,考虑到游戏管理交易的方
你好,我是PHP中的web开发人员,最近迁移到javaEE。我在mysql中创建表。这是第一类: . . . 这是我的第二节课: . . .