Other problems encountered when solving the problem of how to prevent the database from being automatically updated after modifying the properties of the entity in JPA???

I was working on a project recently (spingMVC+jpa+mybatis+spring+mysql+...), and encountered some thorny problems during the period. The key part of the code is pasted here as follows.

When the modification is performed, the specified user is obtained according to the ID, and the status of the obtained entity will be different?

If the transaction annotation propagation = Propagation.NOT_SUPPORTED of the findById method of the DAO layer is removed, the status of the entities obtained during modification will be the same, and they are all persistent!

why? ? Very puzzled! I hope the experts can help to clear up the confusion! ! !

 

    The code of the Service layer is as follows:

@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {
	
	@Autowired
	DAO<?> dao;
	
	/** log*/
	private final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

	@Override
	@Transactional(readOnly = true)
	public TUser getUserById(final String id) {
		TUser user = this.dao.findById(id, TUser.class);
		this.dao.contains(user);
		return user;
	}

	@Override
	@Transactional(rollbackFor = {Exception.class}, propagation = Propagation.REQUIRED)
	public void saveOrUpdateUser(TUser user) {
		synchronized (logger) {
			if (user != null) {
				String error = null;
				if (StringUtils.isBlank(user.getId())) {
					// New users
					user.setId(PlatformTools.getID());
					user.setPassword(MD5Utils.md5(user.getPassword()));
					PasswordEncrypt passwordHelper = new PasswordEncrypt();
					passwordHelper.encryptPassword(user);// encrypted password
					this.dao.save(user);
				} else {
					// modify user
					//************************************************************************************************
					TUser entity = this.getUserById(user.getId()); // 1. The returned entity is free
					//TUser entity = this.dao.findById(user.getId(), TUser.class); // 2. The returned entity is a persistent state
					//************************************************************************************************
					if (entity == null) {
						error = "User information does not exist!";
						logger.error(error);
						throw new BusinessException(error);
					}
					entity.setUserName(user.getUserName());
					entity.setSex(user.getSex());
					entity.setBirthDate(user.getBirthDate());
					entity.setSignCard(user.getSignCard());
					entity.setEmail(user.getEmail());
					//In the free state, the update method needs to be called to actually execute the SQL statement;
					//And there is no need to execute this method when instantiating the state, just call the set method of the above property, and the SQL statement can also be executed when the transaction is committed
					this.dao.update(entity);
				}
			}
		}
	}

	@Override
	@Transactional(rollbackFor = {Exception.class})
//	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public void deleteUser(String[] ids) {
		synchronized (logger) {
			if (ids != null && ids.length > 0) {
				/*this.dao.delete(ids, TUser.class);*/
				for (String id : ids) {
					if (StringUtils.isNotBlank(id)) {
						TUser user = this.getUserById(id);
						if (user != null) {
							this.dao.delete(user);
						}
					}
				}
			}
		}
	}

}

 

    The code of the Dao layer is as follows:

@Repository("daoSupport")
@Scope("singleton")
public class DaoSupport<T> implements DAO<T> {
	
	Logger log = LoggerFactory.getLogger(DaoSupport.class);

	@PersistenceContext
	@Qualifier(value = "entityManagerFactory")
	private EntityManager em;

//	@SuppressWarnings("rawtypes")
	@Autowired
	SqlDao<?> sqlDao;
	
	
	public boolean contains(Object entity){
		boolean bl = em.contains(entity);
		log.info("Whether the entity object is in the [persistent state]:" + bl);
		return bl;
	}

    @SuppressWarnings("hiding")
	@Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
	public <T> T findById(String id, Class<T> clazz) {
		Domain domain = (Domain) em.find(clazz, id);
		log.info("[Persistent state]:" + em.contains(domain));
		return (T) domain;
	}
}

 

    I wanted to mark the key parts of the code with different colors, please forgive me, I can't use it, no matter how to set the preview~

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326713995&siteId=291194637