我们正在为我们的应用程序使用Spring Data Jpa,Spring启动。当我们尝试在@Entity类上使用@Version注释将并发解决方案引入我们的项目时,问题就出现了。
@Annotation正在运行,因为日志显示更新是在版本=?下执行的子句,但它不会抛出任何异常,目标实体会更新。问题出在哪里?
似乎某种实体的版本在hibernate中被缓存了?
根据问题识别可能重复,我想解决下一个审查的解释。我不想做手动版本管理。我想让春天来管理它们。在我的情况下,我认为一些应用程序配置行为不端。正如我在评论中提到的那样,我怀疑的眼睛是针对Hibernate的,它使用旧版本(v1)编号来缓存对象。然后当有人更新db中的实体(制作v2)时,select实体版本是旧的(v1),因此不会抛出任何异常。
如果应用程序使用spring bean的手动配置,是否有任何特殊的版本控制配置?我的意思是没有autoConfig注释。
一些代码段例如:
@Entity
@Table(name="some_object")
@SequenceGenerator(name="seq_some_object", sequenceName="seq_survey")
@Getter
@Setter
@ToString
@NoArgConstructor
@EqualsAndHashCode
public class SomeObject implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "seq_some_object")
private Long id;
@Version
private Long version = -1L;
private Long testValue = -1L;
}
@Service
public class SomeObjectServiceImpl implements SomeObjectService{
@Autowired
private SomeObjectRepository someObjectRepository;
@Override
@Transactional
public void update(SomeObject someObject) {
Long version = someObjectRepository.getVersion(someObject.getId());
if(version != someObject.getVersion())
throw new SomeObjectOldVersionException();
someObject.setVersion(someObject.getVersion() + 1);
someObjectRepositoryRepository.saveAndFlush(someObject);
}
}
TEST QUERY:
public interface SomeObjectRepository extends jpaRepository<SomeObject, Long>{
@Lock(LockModeType.READ)
@Query("SELECT s.version FROM SomeObject s WHERE s.id = :id")
Long getVersion(@Param("id") Long id);
}
进一步说明: 在上面的示例中,如果我使用版本字段操作。让我们假设版本与定义的相同。当我使用2个不同的用户对比对象然后其中一个更新实体时,数据库中的版本值增量(现在等于 0 )。然后当第二个试图做同样的事情版本值错误时,意味着来自存储库返回值的 getVersion(Long id)方法是 -1L ;
现在我们假设我以完全相同的方式完成所有操作,但使用 testValue 字段。在那种情况下,我得到正确的对象版本,一切看起来都很好。
我认为当前的问题与此问题有某种联系。请看Spring 4 MVC updates entity before modifying post request
解
问题描述背景和解决方案在本主题中。 Spring 4 MVC updates entity before modifying post request