Reputation: 12895
In the following code, CustomerService.test() method persists the customer object implicitly, i.e. without any call to merge() or update(). Why is this the case and how can I force it to persist the entities only when I explicitly call merge/update?
Controller :
@Controller
@RequestMapping("/samples")
public class Samples {
@Autowired
private CustomerService customerService;
@RequestMapping(value = "/test", method = RequestMethod.GET)
@ResponseBody
public String test(){
customerService.test();
return "ok";
}
}
Service :
@Service
@Transactional
public class CustomerService {
@Autowired
private BaseDao baseDao;
public Customer findById(Long id) {
return baseDao.find(Customer.class,id);
}
public void test() {
Customer customer = findById(1L);
customer.setEmail("[email protected]");
}
}
Dao :
@Repository("baseDao")
public class BaseDao {
@PersistenceContext
private EntityManager em;
public void create(BaseEntity entity) {
em.persist(entity);
}
public <T> List<T> list(Class<T> entityClass) {
Session session = (Session) em.getDelegate();
List<T> list = session.createCriteria(entityClass).list();
return list;
}
public <T> T find(Class<T> entityClass, long primaryKey) {
return em.find(entityClass, primaryKey);
}
public <T> T update(T entity) {
return em.merge(entity);
}
public void remove(BaseEntity entity) {
em.remove(entity);
}
public void remove(Class<? extends BaseEntity> entityClass, long primaryKey) {
BaseEntity entity = em.find(entityClass, primaryKey);
if (entity != null) {
em.remove(entity);
}
}
}
Upvotes: 4
Views: 2395
Reputation: 2204
You need to be aware that the method test
is within a Hibernate transaction. Therefore you need to know your entity life cycle.
After you load your entity, its state is Persistent. When you commit the transaction, Hibernate checks all persistent entities within the transaction: if they are dirty (have changes), they are updated.
Looking up that diagram, either you can evict()
your entity or change its email after the transaction.
Upvotes: 4