我的代码在很长一段时间内工作得很好,但经过几次重构之后,我注意到我突然无法再保存一个Group对象了.
我遇到了可怕的Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)错误.谷歌搜索之后当然我发现了这个StackOverflow问题,但它根本没有帮助我,因为我没有同时做任何事情.
经过我的重构后,我发现的唯一区别就是这种变化.
之前:
final Collection<Sample> allByBarcode = sampleService.byBarcode(groupRequest.getSamples(), currentUser);
if (!allByBarcode.isEmpty()) {
Group group = new Group();
group.setName(groupRequest.getName());
group.setSamples(allByBarcode);
group.setType(groupRequest.getType());
group.setOwner(currentUser);
group = repository.save(group);
return Optional.ofNullable(group);
}
Run Code Online (Sandbox Code Playgroud)
重构后(不记得具体原因)它成了:
final Collection<Sample> allByBarcode = sampleService.byBarcode(groupRequest.getSamples(), currentUser);
if (!allByBarcode.isEmpty()) {
Group group = new Group();
group.setName(groupRequest.getName());
group.setSamples(new HashSet<>(allByBarcode));
group.setType(groupRequest.getType());
group.setOwner(currentUser);
group = repository.save(group);
return Optional.ofNullable(group);
}
Run Code Online (Sandbox Code Playgroud)
将它改回原来后,它每次都突然重新开始工作,没有任何错误.
任何人都可以解释这个错误的原因是什么,因为这实际上是代码中唯一的区别使它再次起作用?
更新1:
我尝试了另一种变体:
Group group = new …Run Code Online (Sandbox Code Playgroud) 我开始向您展示我的情况。
这是我的父对象:
@Entity
@Table(name="cart")
public class Cart implements Serializable{
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
@OneToMany(mappedBy="cart", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<CartItem> cartItems;
...
}
Run Code Online (Sandbox Code Playgroud)
这是我的孩子对象:
@Entity
@Table(name="cart_item")
public class CartItem implements Serializable{
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Id
@Column(name="id")
private Integer id;
@ManyToOne
@JoinColumn(name="cart_id", nullable=false)
private Cart cart;
...
}
Run Code Online (Sandbox Code Playgroud)
正如您看到数据库一样,在表cart_item(子对象)中,字段cart_id具有指向表cart(父对象)的字段ID的外键。
这是我保存对象的方式:
1)有一个restController,它读取一个JSON对象:
@RestController
@RequestMapping(value = "rest/cart")
public class CartRestController {
@Autowired
private CartService cartService;
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.CREATED) …Run Code Online (Sandbox Code Playgroud) 我不明白,我的服务出了什么问题。我收到org.hibernate.StaleObjectStateException尝试运行此方法:
fun updateNameForPhone(phone: String, name: String): Client {
val res = clientRepository.findByPhone(phone) ?: throw ClientNotFoundException(phone)
res.name = name
return clientRepository.save(res)
}
Run Code Online (Sandbox Code Playgroud)
客户端存储库:
@Repository
interface ClientRepository : JpaRepository<Client, UUID> {
fun findByPhone(phone: String): Client?
}
Run Code Online (Sandbox Code Playgroud)
客户实体:
@Entity
data class Client(
var name: String = "",
var phone: String = "",
@Id @GeneratedValue(strategy = GenerationType.AUTO)
val uuid: UUID = defaultUuid()
)
Run Code Online (Sandbox Code Playgroud)
例外:
类 [com.app.modules.client.domain.Client] 的对象,标识符为 [12647903-7773-4f07-87a8-e9f86e99aab3]:乐观锁定失败;嵌套异常是 org.hibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存值映射不正确):[com.app.modules.client.domain.Client#12647903-7773-4f07-87a8-e9f86e99aab3] ”
是什么原因?我正在使用 Kotlin 1.3.11、Spring Boot 2.1.1、MySql。我不在不同的线程中运行它,只是尝试单个请求。
我有以下行动:
def index() {
User.withNewTransaction {
def user = User.get(params.userId)
user.name = "test"
user.save(flush:true)
response.setContentType("image/gif")
response.outputStream << PIXEL_BYTES_OF_A_GIF_IMAGE
return
}
}
Run Code Online (Sandbox Code Playgroud)
运行时,我有时会收到以下错误:
Message
Executing action [index] of controller [test.TestController] caused exception: Runtime error executing action
Caused by
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [test.User#1]
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种错误?我以为withNewTransaction会阻止这个错误.
hibernate ×4
spring ×3
java ×2
grails ×1
grails-2.0 ×1
jpa ×1
kotlin ×1
many-to-one ×1
one-to-many ×1
spring-boot ×1
transactions ×1