I\'m trying to implement a simple DAO. I have a Dao:
@Repository(\"iUserDao\")
@Transactional(readOnly = true)
public class UserDao implements IUserDao {
pri
It works this way because you marked transaction as read only with @Transactional(readOnly = true)
.
As you can see, it doesn't make your transactions actually read-only since you still can persist changes by calling flush()
manually. However, it disables automatic flush at the end of transaction, so that changes are not persisted without manual flush.
You need either remove readOnly
from class-level annotation, or override it on non-read-only methods with method-level annotations:
@Override
@Transactional(readOnly = false)
public boolean save(User user) { ... }
Also note that transaction demarcation is usually applied to service layer methods, not to DAO methods. In particular, when writing DAO methods you actually don't know which transactions should be read-only, and which are not. This information is available only when designing service layer, as you can see in this example:
public class UserService {
@Autowired UserDAO dao;
@Transactional(readOnly = true)
public User getUserById(int id) {
return dao.getById(id); // getById() can participate in effectively read-only transaction
}
@Transactional
public void changeUserName(int id, String newName) {
User u = dao.getById(id); // Or not
u.setName(newName); // Change will be flushed at the end of transaction
}
}
Try setting the transactional propagation to required, and remove all flush()
:-
@Repository("iUserDao")
@Transactional(propagation=Propagation.REQUIRED)
public class UserDao implements IUserDao {
...
}