如何在Spring Data JPA中阻止自动更新?

huangapple go评论75阅读模式
英文:

How prevent update automatically in Spring Data JPA?

问题

我有一个JPA实体,如下所示:

@Entity
@DynamicUpdate
@TypeDef(name = "json_binary", typeClass = JsonBinaryType::class)
public class Workflow {
   private Long id;
   private String name;

   @Type(type = "json_binary")
   @Column(columnDefinition = "jsonb")
   private List<AccessModel> users;
}

public class AccessModle {
   private String name;
   private Int permission;
}

和Repository:

@Repository
public interface WorkflowRepository extends JpaRepository<Workflow, Long> {}

现在当我只是想要查找一个workflow(repository.findById(1)),Hibernate日志如下所示:

Hibernate: select workflow0_.id as id1_12_0_, workflow0_.name as name2_12_0_, 
           workflow0_.users as users3_12_0_ where workflow0_.id=?
Hibernate: update workflow set users=? where id=?

我没有修改users,但Hibernate设置了它。如何防止自动更新实体?

更新:

@Service
@Transactional
public class WorkflowServiceImpl {

    @Autowired
    private WorkflowRepository repository;

    public Workflow find(Long id) {
        return repository.findById(id);
    }
}
英文:

I have a JPA entity as follow:

@Entity
@DynamicUpdate
@TypeDef(name = &quot;json_binary&quot;, typeClass = JsonBinaryType::class)
public class Workflow {
   private Long id;
   private String name;

   @Type(type = &quot;json_binary&quot;)
   @Column(columnDefinition = &quot;jsonb&quot;)
   private List&lt;AccessModel&gt; users;
}

public class AccessModle {
   private String name;
   private Int permission;
}

And the repository:

@Repository
public interface WorkflowRepository extends JpaRepository&lt;Workflow, Long&gt; {}

Now when I just want to find a workflow(repository.findById(1)), The hibernate log is as follow:

Hibernate: select workflow0_.id as id1_12_0_, workflow0_.name as name2_12_0_, 
           workflow0_.users as users3_12_0_ where workflow0_.id=?
Hibernate: update workflow set users=? where id=?

I didn't modify users, But Hibernate set it. How can I prevent automatically update entity?

Update:

@Service
@Transactional
public class WorkflowServiceImpl {

    @Autowired
    private WorkflowRepository repository;

    public Workflow find(Long id) {
        return repository.findById(id);
    }
}

答案1

得分: 2

你已在服务级别添加了 @Transactional,因此它将适用于服务类中的每个方法。您需要在您的 find(Long id) 方法上添加 @Transactional(readOnly = true)。这将解决您的问题。

最佳做法是仅在需要的方法上添加 @Transactional,而不是在类级别添加。

英文:

You have added @Transactional at service level so, it will be applicable for each method present in the service class. You need to add @Transactional(readOnly = true) on your find(Long id) method. It will solve your problem.

@Service
@Transactional
public class WorkflowServiceImpl {

    @Autowired
    private WorkflowRepository repository;

    @Transactional(readOnly = true)
    public Workflow find(Long id) {
        return repository.findById(id);
    }
}

It is best practice to add the @Transactional on required methods only instead at the class level.

答案2

得分: 1

你可以在@Column的定义中包括以下属性(insertable = false, updatable = false)--

@Column(columnDefinition = "jsonb", insertable = false, updatable = false)

这将阻止插入或更新users的值。

英文:

You can include the following properties (insertable = false, updatable = false) along with the definition for @Column --

@Column(columnDefinition = &quot;jsonb&quot;, insertable = false, updatable = false)

This will prevent from inserting or updating the value for the users

huangapple
  • 本文由 发表于 2020年8月9日 18:08:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/63325035.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定