java - 为什么我不能在没有 LockTimeoutException 的情况下合并()我的域对象?

标签 java hibernate orm concurrency transactions

我正在使用 hibernate 作为我的持久层创建一个 CRUD API。

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

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

创建工作正常,但更新失败并出现 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;
    }
}

BaseDAO 代码(ClientDAO 扩展 BaseDAO)

public class BaseDAO {
    public Boolean save(Object object) {
        Session session = getSession();
        Transaction tx = session.beginTransaction();
        session.save(object);
        tx.commit();
        session.close();
        return Boolean.TRUE;
    }

    public Boolean update(Object object) {
        Session session = getSession();
        Transaction tx = session.beginTransaction();
        session.merge(object);
        tx.commit();
        session.close();
        return Boolean.TRUE;
    }

    public Session getSession() 
    {
        return HibernateSessionFactory.getSession();
    }   
}

入口点代码

@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)。

最佳答案

发生这种情况的唯一方法是您有两个数据库连接,它们都试图修改同一个实体。

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

关于java - 为什么我不能在没有 LockTimeoutException 的情况下合并()我的域对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31645457/

相关文章:

java - 是否必须在aspectJ中实现具体方面

java - 为什么我不能删除并绘制相同的 java 对象?

java - Android 应用程序因 NPE 崩溃

java - Spring 错误 - NoSuchBeanDefinitionException :SessionFactory

java - 使用 Hibernate ORM 和 OGM 结合 SQL 和 NOSQL 数据库

java - Hibernate:多对多加入继承策略的方法

java - 使用 JPA 工具进行对象关系映射 : Generate Tables from Entities feature

java - OWLApi 访客模式 : get superClass axiom

java - Hibernate 模型类是否有包命名约定?

SQL、MVC、 Entity Framework