JPA実装としてHibernateを使用するSpringブートJPA(spring-boot-startter-data-jpa依存性)を使用するプロジェクトがあります。SpringブートJPAはセッションにエンティティをアタッチしません
私はコンテナを自動的に設定しました(@EnableAutoConfiguration)、私はCRUD操作にEntityManagerを使用します。
問題: 私はHQLを経由して、起動時に私のエンティティをロードするには、このEntityManagerを使用してクエリが、私はそれらのいずれかを編集したり削除したいとき、私は次のようなエラーに
org.springframework.dao.InvalidDataAccessApiUsageExceptionを取得します:デタッチされたインスタンスの削除com.phistory.data.model.car.Car#2; java.lang.IllegalArgumentException:デタッチされたインスタンスの削除com.phistory.data.model.car.Car#2
org.springframework.dao.InvalidDataAccessApiUsageException:エンティティが管理されていません。ネストされた例外は、java.lang.IllegalArgumentExceptionがある:
- 春ブート・スターター・データ-JPA 1.4.4.RELEASE(休止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);
}
}
データベースの設定(ない豆は明示的に宣言されていないが、EntityManagerが自動的にauの取得しますtowired):
@Configuration
@ComponentScan("com.phistory.data.dao")
@EntityScan("com.phistory.data.model")
@EnableTransactionManagement
@PersistenceUnit
public class SqlDatabaseConfig {
}
DAO
@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);
}
}
は、なぜ私はロードエンティティがセッションに接続されていませんか?エンティティはその時点で管理してはいけないので、新しいエンティティを保存することは明らかです。あなたはDAOの外DAOのメソッドを呼び出すと、多く 挨拶
プレミアムなもの!私は@Repositoryがそれを書くことなくCRUDロジックを注入するのに使用できることを知らなかった、これは実際には私がSpring Bootを使用するようにアップグレードした古いプロジェクトだが、出てきたすべての新機能長年にわたって。私はこの方法ですべてのDAOを書き直します、ありがとう! – GCarbajosa
私はあなたを助けることができてうれしいです! :) –