我正在尝试更新数据库中已经存在的对象。保存对象可以正常工作,但是在调用更新时,我的日志显示一条select语句,但没有更新。以下是我的代码。
实体
@Entity
@Table(name = "items")
public class Items implements Serializable {
private static final long serialVersionUID = -3607451001182083512L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer iditems;
@ManyToOne
@JoinColumn(name = "idcategories")
private Categories categories;
@Size(min = 1, max = 35)
private String name;
@Size(min = 0, max = 100)
private String description;
private double price;
private int hidden;
private String upc;
@OrderColumn
@ManyToMany(cascade = { CascadeType.MERGE }, fetch = FetchType.LAZY)
@JoinTable(name = "itemsextrascat", joinColumns = { @JoinColumn(name = "iditems") }, inverseJoinColumns = { @JoinColumn(name = "idextrascat"), })
private Set<Extrascat> extrascat = new HashSet<Extrascat>();
Getters and Setters
}
服务
@Service("itemsService")
public class ItemsService {
@Autowired
private ItemsDao itemsDao;
// CREATE OR UPDATE ITEM
@PreAuthorize("hasRole('ADMIN')")
public void createOrUpdate(Items items) {
itemsDao.createOrUpdate(items);
}
// CREATE OR UPDATE ITEM
@PreAuthorize("hasRole('ADMIN')")
public void update(Items items) {
itemsDao.update(items);
}
}
DAO
@Transactional
@Component("itemsDao")
public class ItemsDao {
@Autowired
private EntityManagerFactory entityManagerFactory;
// CREATE OR UPDATE ITEM
@PreAuthorize("hasRole('ADMIN')")
public void update(Items items) {
Session session = entityManagerFactory.unwrap(SessionFactory.class).openSession();
session.unwrap(Session.class).merge(items);
}
}
我尝试使用保存更新持久合并全部无济于事。我还尝试根据我在其他帖子上看到的内容更改@Transactional
的位置。我还确保我的方法不是私有的,以确保引发@Transational
。我能够通过实现一个Repository来解决该问题,该Repository允许我更新实体。但是,我实际上并不想在代码中同时使用DAO和存储库。关于为什么Dao实现不起作用的任何想法?
答案 0 :(得分:1)
您使道变得太复杂了。首先,为什么要使用本机休眠模式,而普通的EntityManager
就足够了。为什么使用EntityManagerFactory
来管理自己的EntityManager
。最后,您处于Spring托管环境中,请不要使用openSession
或createEntityManager
,因为这将使您成为非事务性环境。
话虽如此,您可以删除大部分代码。
@Transactional
@Component("itemsDao")
public class ItemsDao {
@PersistenceContext
private EntityManager em;
// CREATE OR UPDATE ITEM
@PreAuthorize("hasRole('ADMIN')")
public void update(Items items) {
em.merge(items);
}
}
这就是您所需要的。基本上不要使用openSession
,因为这会为您提供新的Session
休眠状态。如果做得足够好,最终将导致使用所有数据库连接时应用程序无响应。这是因为您正在打开会话,但从未关闭它。
但是,我建议您使用Spring Boot和JPA来简单地使用Spring Data JPA,以便让它处理所有这些事情。
public interface ItemsRepository extends CrudRepository<Items, Long> {}
然后,在您的代码中只需在save
上调用ItemsRepository
方法,Spring Data JPA将为您完成所有令人讨厌的工作。