欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在解决JPA中 如何防止修改实体的属性后不自动更新数据库问题时遇到的其它问题??? daojavajpa 

程序员文章站 2022-03-13 09:18:00
...

最近在做一个项目(spingMVC+jpa+mybatis+spring+mysql+...),期间遇到一些棘手的问题,这里贴上关键部分代码如下。

在执行修改的时候根据ID获取指定用户,拿到的实体的状态会不一样呢?

如果将DAO层的findById方法的事务注解  propagation = Propagation.NOT_SUPPORTED  去掉的话,修改时拿到的实体的状态就都是一样的,都是持久化状态的!

为什么呢??很是不解!希望高手们帮忙解惑下!!!

 

    Service层部分代码如下:

@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {
	
	@Autowired
	DAO<?> dao;
	
	/** 日志 */
	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())) {
					// 新增用户
					user.setId(PlatformTools.getID());
					user.setPassword(MD5Utils.md5(user.getPassword()));
					PasswordEncrypt passwordHelper = new PasswordEncrypt();
					passwordHelper.encryptPassword(user);// 加密密码
					this.dao.save(user);
				} else {
					// 修改用户
					//************************************************************************************************
					TUser entity = this.getUserById(user.getId());			// 1、返回的实体是游离状态
					//TUser entity = this.dao.findById(user.getId(), TUser.class);	// 2、返回的实体是持久化状态
					//************************************************************************************************
					if (entity == null) {
						error = "用户信息不存在!";
						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());
					//游离状态时需要调用该update方法才可真正执行SQL语句;
					//而实例化状态时无需执行该方法,只需调用上面属性的set方法,待事务提交时也可执行SQL语句
					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);
						}
					}
				}
			}
		}
	}

}

 

    Dao层部分代码如下:

@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("实体对象是否处于【持久化状态】:" + 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("【持久化状态】:" + em.contains(domain));
		return (T) domain;
	}
}

 

    本想把代码关键部分用不同颜色标注出来,请原谅我不会用,怎么设置预览都不行~

相关标签: dao java jpa