SpringData修改和删除操作

SpringData的查询我们已经学完了,我们现在就研究一下SpringData的修改和删除。

@Modifying 注解和事务

  • @Query 与 @Modifying 这两个 annotation一起声明,可定义个性化更新操作,例如只涉及某些字段更新时最为常用,示例如下:
  • //可以通过自定义的 JPQL 完成 UPDATE 和 DELETE 操作. 注意: JPQL 不支持使用 INSERT
    //在 @Query 注解中编写 JPQL 语句, 但必须使用 @Modifying 进行修饰. 以通知 SpringData, 这是一个 UPDATE 或 DELETE 操作
    //UPDATE 或 DELETE 操作需要使用事务, 此时需要定义 Service 层. 在 Service 层的方法上添加事务操作.
    //默认情况下, SpringData 的每个方法上有事务, 但都是一个只读事务. 他们不能完成修改操作!
    
    @Modifying
    	@Query("UPDATE Person p SET p.lastName = :lastName WHERE id = :id")
    	void updatePersonName(@Param("id") Integer id, @Param("lastName") String lastName);
    

      

  • 注意: 方法的返回值应该是 int,表示更新语句所影响的行数 在调用的地方必须加事务,没有事务不能正常执行

上面会出现错误,是因为我们没有加入事务出错,错误的信息是:

org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:413)
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:156)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
	at com.sun.proxy.$Proxy22.updatePersonName(Unknown Source)
	at com.fxr.test.SpringDataTest.testModifyingAnnotation(SpringDataTest.java:67)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query
	at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:96)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:328)
	at com.sun.proxy.$Proxy24.executeUpdate(Unknown Source)
	at org.springframework.data.jpa.repository.query.JpaQueryExecution$ModifyingExecution.doExecute(JpaQueryExecution.java:174)
	at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:61)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:95)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:85)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:323)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
	... 31 more

解决上述的问题:首先定义一个PersonService类

package com.fxr.springdata;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PersonService {

	@Autowired
	private PersonRepsotory personRepsotory;

	@Transactional
	public void updataPerson(String lastName,Integer id){
		personRepsotory.updatePersonName(id, lastName);
	}

}

  在Service类上加事务的注解。就解决上述的问题。

  

事务

  • Spring Data 提供了默认的事务处理方式,即所有的查询均声明为只读事务。
  • 对于自定义的方法,如需改变 Spring Data 提供的事务默认方式,可以在方法上注解 @Transactional 声明 
  • 进行多个 Repository 操作时,也应该使它们在同一个事务中处理,按照分层架构的思想,这部分属于业务逻辑层,因此,需要在 Service 层实现对多个 Repository 的调用,并在相应的方法上声明事务。
时间: 2024-10-26 07:20:08

SpringData修改和删除操作的相关文章

ASP.NET MVC3 实例(六) 增加、修改和删除操作(二)

http://www.jquery001.com/asp.net-mvc3-instance-add-update-delete2.html 上篇我们在 ASP.NET MVC3 中实现了添加操作,由于时间关系没有完成修改.删除操作,我们新建了一个名为"Contact"的 Controller,并实现了添加方法,下边就让我们在此基础上来完成 ASP.NET MVC3 中的修改和删除操作. 首先,我们在 Contact 控制器类中添加一个名为 View()的方法,用来从 Contact

Android数据库高手秘籍(六)——LitePal的修改和删除操作

——LitePal的存储操作 . LitePal的项目地址是:https://github.com/LitePalFramework/LitePal 传统的修改和删除数据方式 上篇文章中我们已经得知,SQLiteDatabase类中提供了一个insert()方法用于插入数据,那么类似地,它还提供了update()和delete()这两个方法,分别用于修改和删除数据.先来看一下update()方法的方法定义: [java] view plaincopy public int update(Stri

MySQL数据库表的数据插入、修改、删除操作及实例应用

1.MySQL数据库表的数据插入.修改.删除操作SQL语法格式: 1 CREATE DATABASE db0504; 2 3 USE db0504; 4 5 CREATE TABLE student ( 6 sno VARCHAR (10) NOT NULL UNIQUE PRIMARY KEY, 7 sname VARCHAR (20) NOT NULL, 8 ssex enum ('男', '女') NOT NULL DEFAULT '男', 9 sbirth date, 10 sclass

跟我一起学extjs5(18--模块的新增、修改、删除操作)

跟我一起学extjs5(18--模块的新增.修改.删除操作) 上节在Grid展示时做了一个金额单位可以手工选择的功能,如果你要加入其他功能,也只要按照这个模式来操作就行了,比如说你想改变金额字段的颜色.小数位数.零值是否显示.货币符号.单位显示在标题栏或者跟在金额后面,凡是你能想到的需要手工设置的东西都可以加进来. 上面讲到的这些设置以后会加到程序里,在下载包里可以看到,就不做讲解了. 这一节来使模块可以具有新增.修改.删除的操作.由于还没有和后台服务相联,因此数据是保存在本地localStor

带有条件 修改和删除操作 如何解决

使用@Query 注解完成 , 搭配使用@Modifying 标记修改.删除操作将记录 1 的 最小长度改为 15注意:使用单体测试,测试 DAO ,要添加事务,设置事务不回滚 原文地址:https://blog.51cto.com/13587708/2420657

4. mongodb插入,修改,删除操作

mongodb插入操作 语法: db.collection.save(collections); OR  db.collection.insert(collections); 插入有上面两种方式. 1. 借用对象来插入 >item={id:1,name:"hello"} >db.lottu.insert(item) 2. 循环插入数据:一下子插入5条记录这种很不错吧 >for(i=1;i<=5;i++)db.lottu.insert({id:i,name:&qu

数据库————表之增加、查询、修改、删除操作

一. 运算符: 字符串是用单引号 数据库中出现比较用的是=,不是双等号 逻辑与 and 逻辑或 or 逻辑非 not 二.CRUD操作: 1.C——create   增加.创建,向数据库添加数据 格式:insert into 表名  values(列值1,列值2,...........列值n) insert into Fruit values('K009','苹果',3.0,'高青',90,'') insert into Fruit(Ids,Name,Price,Source,Numbers)

Git学习版本回退和管理文件的修改及删除操作

版本回退 前面我们成功的提交了一次mygit.txt,下面咱对它进行修改,内容如下: Hello Git Git is so easy. 然后用git status来跟踪该文件的状态: 可以看到hellogit.txt已经被修改过了,到底这次修改的内容与上次的内容有什么不同的,咱们可以使用git diff查看: 当然你也可以查看上次提交的信息,使用git log: 通过前面一章我们知道,该文件还处于工作区,因此我们又可以使用add.commit操作了: 这里笔者偷了个懒,直接用-m表示提交的信息

DOM综合例题之对图书添加、修改、删除操作

图书管理界面: 法一:通过childNodes属性来获取所有子节点,然后再取子节点的值 法二: 添加图书信息: 添加界面如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999