Java 为什么可以';t I merge()我的域对象没有LockTimeoutException?

Java 为什么可以';t I merge()我的域对象没有LockTimeoutException?,java,hibernate,orm,concurrency,transactions,Java,Hibernate,Orm,Concurrency,Transactions,我正在使用hibernate作为持久层创建CRUDAPI API接受JSON并将其序列化为POJO。然后,管理层将POJO转换为新的Hibernate域对象 对于Create和Update运行的代码完全相同-唯一的区别是对于Update我还设置了hibernate对象的ID字段 创建工作正常,但更新失败,出现org.hibernate.exception.LockTimeoutException。经过几个小时的窥探,我要挥舞白旗,希望有人能解释我是白痴的所有原因 客户端管理器代码 public

我正在使用hibernate作为持久层创建CRUDAPI

API接受JSON并将其序列化为POJO。然后,管理层将POJO转换为新的Hibernate域对象

对于
Create
Update
运行的代码完全相同-唯一的区别是对于
Update
我还设置了hibernate对象的ID字段

创建工作正常,但更新失败,出现
org.hibernate.exception.LockTimeoutException
。经过几个小时的窥探,我要挥舞白旗,希望有人能解释我是白痴的所有原因

客户端管理器代码

public class ClientManager {

    private static final ClientDAO clientDAO = new ClientDAO();

    ...

    public Client updateClient(ClientVO inputVO) {

        // Generate a Client from the input
        Client client = ClientManager.generateClient(inputVO);
        client.setClientKey(Integer.parseInt(inputVO.getPersonalId()));
        client.setUpdateDate(new Date());
        client.setUpdateTimestamp(new Date());

        // Update the client
        clientDAO.update(client);

    }

    ...

    public static Client generateClient(ClientVO clientVO) {
        Client client = new Client();

        client.setFirstName(clientVO.getFirstName());
        client.setMiddleName(clientVO.getMiddleName());
        client.setLastName(clientVO.getLastName());

        return client;
    }
}
@PUT
@Path("clients/{personalId}")
@Produces({MediaType.APPLICATION_JSON})
public String updateClient(@PathParam("personalId") String personalId, String data) throws JsonParseException, JsonMappingException, IOException {
    ClientVO inputVO = om.readValue(data, ClientVO.class);
    inputVO.setPersonalId(personalId);

    ClientVO outputVO = clientManager.updateClient(inputVO);
    return om.writeValueAsString(outputVO);
}
BaseDAO代码(ClientDAO扩展BaseDAO)

入口点代码

public class ClientManager {

    private static final ClientDAO clientDAO = new ClientDAO();

    ...

    public Client updateClient(ClientVO inputVO) {

        // Generate a Client from the input
        Client client = ClientManager.generateClient(inputVO);
        client.setClientKey(Integer.parseInt(inputVO.getPersonalId()));
        client.setUpdateDate(new Date());
        client.setUpdateTimestamp(new Date());

        // Update the client
        clientDAO.update(client);

    }

    ...

    public static Client generateClient(ClientVO clientVO) {
        Client client = new Client();

        client.setFirstName(clientVO.getFirstName());
        client.setMiddleName(clientVO.getMiddleName());
        client.setLastName(clientVO.getLastName());

        return client;
    }
}
@PUT
@Path("clients/{personalId}")
@Produces({MediaType.APPLICATION_JSON})
public String updateClient(@PathParam("personalId") String personalId, String data) throws JsonParseException, JsonMappingException, IOException {
    ClientVO inputVO = om.readValue(data, ClientVO.class);
    inputVO.setPersonalId(personalId);

    ClientVO outputVO = clientManager.updateClient(inputVO);
    return om.writeValueAsString(outputVO);
}
请注意,clientKey是主键

超时发生在BaseDAO的update()方法中的
.commit()


如果有用的话,我很乐意提供更多的代码(例如ClientVO)。

实现这一点的唯一方法是,您有两个数据库连接,它们都试图修改相同的实体


如果这种情况发生在单个用户身上,那是因为您没有对整个请求使用相同的会话,而是创建了多个会话。我想说的是,您在某个外部级别打开了一个Hibernate会话和一个事务,当调用update方法时,您打开了另一个会话和一个新事务,该会话和事务与可能已在同一实体上获取锁的外部会话和事务冲突(因为您加载了该实体并对其进行了更改).

这是一个非常有用的思路——我只是通过收紧我的会话来确保我
.close()
正确地完成它们,但遗憾的是,这个问题仍然存在。我会继续挖掘,以防我遗漏了什么,并且我正在更新问题以显示入口点。我有理由相信我在这一点上没有包装事务——是否有可能Hibernate正在做奇怪的事情,因为我正在手动设置原始域对象的主键,而不是“查找”对象?我还通过手动设置实体标识符以及来自DTO的其他属性来更新实体。这是导致您出现问题的数据库锁。您是否使用一些触发器来获取其他表中其他数据库行的锁?没有触发器,模式非常简单,定义如下:| |我将继续挖掘,并在了解更多信息后报告。很好地理解了我所做的并不是天生违反了关于hibernate的某些东西。