代码之家  ›  专栏  ›  技术社区  ›  Marios

弹簧引导2休眠更新未插入

  •  0
  • Marios  · 技术社区  · 6 年前

    我正在尝试更新数据库中已存在的对象。保存一个对象很好,但是当调用更新时,我的日志会显示一个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);
        }
    
    }
    

    @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 正在被唤起。我通过实现一个允许我更新实体的存储库来解决这个问题。但是,我不希望在代码中同时使用DAO和存储库。关于DAO实现为什么不起作用有什么想法吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   M. Deinum    6 年前

    你的刀太复杂了。首先,为什么要在平原 EntityManager 就够了。为什么使用 EntityManagerFactory 管理自己的 实体管理器 . 最后,你在一个由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);
        }
    }
    

    这就是你所需要的。基本上不使用 旋光 因为这会给你一个新的 Session 用于休眠。如果您最终做的足够多,那么当使用所有DB连接时,您最终也将得到一个没有响应的应用程序。这是因为您正在打开会话,但从未关闭它。

    不过,我建议您使用SpringBoot和JPA来简单地使用SpringDataJPAEnLet来处理所有这些问题。

    public interface ItemsRepository extends CrudRepository<Items, Long> {}
    

    然后在代码中,只需调用 save 方法在 ItemsRepository 而SpringDataJPA将为您做所有讨厌的事情。