【发布时间】:2017-08-10 07:05:00
【问题描述】:
我有一个使用 Spring Boot JPA(spring-boot-starter-data-jpa 依赖项)的项目,它使用 Hibernate 作为 JPA 实现。
我已自动配置容器 (@EnableAutoConfiguration),并且我使用 EntityManager 进行 CRUD 操作。
问题: 我在启动时使用此 EntityManager 通过 HQL 查询加载我的实体,但是当我想编辑或删除其中任何一个时,我收到以下错误
org.springframework.dao.InvalidDataAccessApiUsageException: 移除一个分离的实例 com.phistory.data.model.car.Car#2;嵌套异常是 java.lang.IllegalArgumentException: Removing a detached instance com.phistory.data.model.car.Car#2
org.springframework.dao.InvalidDataAccessApiUsageException:实体不受管理;嵌套异常是 java.lang.IllegalArgumentException: Entity not managed
图书馆:
- spring-boot-starter-data-jpa 1.4.4.RELEASE (Hibernate 5.0.11.Final)
主要:
@SpringBootApplication
@EnableAutoConfiguration
@Slf4j
public class Main {
public static void main(String[] args) {
try {
SpringApplication.run(Main.class, args);
} catch (Exception e) {
log.error(e.toString(), e);
}
}
数据库配置(没有明确声明 bean,EntityManager 自动自动装配):
@Configuration
@ComponentScan("com.phistory.data.dao")
@EntityScan("com.phistory.data.model")
@EnableTransactionManagement
@PersistenceUnit
public class SqlDatabaseConfig {
}
道
@Transactional
@Repository
public class SqlCarDAOImpl extends SqlDAOImpl<Car, Long> implements SqlCarDAO {
@Autowired
public SqlCarDAOImpl(EntityManager entityManager) {
super(entityManager);
}
@Override
public List<Car> getAll() {
return super.getEntityManager()
.createQuery("FROM Car AS car")
.getResultList();
}
}
父 DAO
@Transactional
@Repository
@Slf4j
@NoArgsConstructor
public abstract class SqlDAOImpl<TYPE extends GenericEntity, IDENTIFIER> implements SqlDAO<TYPE, IDENTIFIER> {
@Getter
@PersistenceContext
private EntityManager entityManager;
public SqlDAOImpl(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void saveOrEdit(TYPE entity) {
if (entity != null) {
if (entity.getId() == null) {
log.info("Saving new entity: " + entity.toString());
this.entityManager.persist(entity);
} else {
log.info("Editing entity: " + entity.toString());
this.entityManager.refresh(entity);
}
}
}
public void delete(TYPE entity) {
if (entity != null) {
log.info("Deleting entity: " + entity.toString());
this.entityManager.remove(entity);
}
}
public Session getCurrentSession() {
return this.entityManager.unwrap(Session.class);
}
}
为什么我加载的实体没有附加到 Session?保存一个新实体显然可以正常工作,因为此时不能管理该实体。
非常感谢 问候
【问题讨论】:
标签: hibernate jpa spring-boot hql