【问题标题】:Issues with @ManyToMany hibernate mapping@ManyToMany 休眠映射的问题
【发布时间】:2021-01-13 10:17:12
【问题描述】:

我是网络开发的新手。我一直在尝试做一个电子商务平台,并使用productwishlist之间的@ManyToMany映射,使用wishlist_product作为连接表。

添加后,我没有遇到错误,但数据未添加到连接表中。我已经尝试解决此问题 2 天了,但一直面临持续失败。我在下面附上了wishlistproduct 的代码。

@Entity
@Table(name = "wishlist")
public class Wishlist {

    @Id
    @Column(name = "username")
    /*
     * @GeneratedValue(generator = "gen")
     * 
     * @GenericGenerator(name = "gen", strategy = "foreign", parameters
     * = @Parameter(name = "property", value = "login"))
     */
    private String username;

    @ManyToMany
    @JoinTable(name = "wishlist_product", 
                joinColumns = @JoinColumn(name = "username"),
                inverseJoinColumns = @JoinColumn(name = "product_id"))
    private List<Electronics> product;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "electronics")
@DiscriminatorColumn(name = "product_Type", discriminatorType = DiscriminatorType.STRING)
public class Electronics {

    @Id
    @GenericGenerator(name = "CamIdGenerator", strategy = "com.virtusa.neuralhack.vlx.IdGenerator.CameraIdGenerator")
    @GeneratedValue(generator = "CamIdGenerator")
    // @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "product_id")
    private String productId;

    private String askingPrice;

    @Column(name = "age")
    private String howOld;

    @Column(name = "model")
    private String model;

    @Column(name = "brand")
    private String brand;

    @Column(name = "description")
    private String description;

    transient private String email;

    @ManyToOne
    @JoinColumn(name = "username")
    private User_Login user;

    @ManyToMany
    @JoinTable(name = "wishlist_product", joinColumns = @JoinColumn(name = "product_id"), inverseJoinColumns = @JoinColumn(name = "username"))
    private List<Wishlist> wishlist;
public void addToWishlist(String email, String productId) {

    Session currentSession = manager.unwrap(Session.class);
    Wishlist wishlist = currentSession.get(Wishlist.class,email);
        
    //System.out.println(wishlist.getUser());
        
    Electronics product = currentSession.get(Electronics.class, productId);
    System.out.println(product);

    wishlist.addToWishlist(product);
        
    //product.addAWishlist(wishlist);
    //System.out.println(wishlist.getProduct().get(0));

    currentSession.saveOrUpdate(wishlist);
}

【问题讨论】:

    标签: spring-boot hibernate many-to-many


    【解决方案1】:

    确保你在读写事务中但不是只读的。

    还有一些建议:

    • 不要将cascade = CascadeType.ALL 与多对多关联一起使用,因为CascadeType.ALL 包含CascadeType.REMOVE,在多对多的情况下会导致太多实体被删除
    • 当您不需要特定顺序时,使用 Set 而不是 List 进行多对关联。

    【讨论】:

    • 感谢您的帮助。我在添加到愿望清单方法中引入了@Transactional 注释,它对我来说就像一个魅力......
    【解决方案2】:

    你应该这样做:

    @Entity
    @Table(name = "wishlist")
    public class Wishlist {
    
        @Id
        @Column(name = "username")
        private String username;
    
        @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
        @JoinTable(name = "wishlist_product", 
                    joinColumns = @JoinColumn(name = "username"),
                    inverseJoinColumns = @JoinColumn(name = "product_id"))
        private List<Electronics> products;
        
        public void addProduct(Electronics product) {
           products.add( product );
           product.getWishlists().add( this );
        }
    
        public void removeProduct(Electronics product) {
          products.remove( product );
          product.getWishlists().remove( this );
        }
    }
    
    
    @Entity
    @Table(name = "electronics")
    public class Electronics {
    
       @Id
       @Column(name = "product_id")
       private String productId;
       
       @ManyToMany(mappedBy = "products")
       private List<Wishlist> wishlists;
    }
    
    1. 只有bidirectional @ManyToMany 的拥有方应由@JoinTable 注释映射。你应该在另一边使用mappedBy

    2. 如果您想传播持久状态和其他状态,您应该在拥有方设置cascade 属性。

    3. 为了保持双方之间的同步性,最好提供辅助方法来添加或删除子实体。

    您的addToWishlist 方法将如下所示:

    public void addToWishlist(String email, String productId) {
       Session currentSession = manager.unwrap(Session.class);
       Wishlist wishlist = currentSession.get(Wishlist.class,email);
       Electronics product = currentSession.get(Electronics.class, productId);
       wishlist.addProduct(product);
       currentSession.saveOrUpdate(wishlist);
    }
    

    【讨论】:

    • Hii @SternK ,我尝试了上述步骤,但结果仍然相同。我应该附上更多代码供参考吗?
    • 也试过改变joinColumns和inverseJoinColumns,但结果没有改变...
    • 我建议你启用休眠属性hibernate.show_sqlhibernate.format_sqlhibernate.use_sql_comments,看看sql hibernate到底执行了什么。我测试了上面的映射,它对我有用。
    • 嘿斯特恩,感谢您一路帮助我。除了您建议的更改之外,我错过了将 @Transactional 注释放在我的服务类方法上。它现在完美运行...谢谢:)
    猜你喜欢
    • 1970-01-01
    • 2018-01-29
    • 2011-01-31
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    相关资源
    最近更新 更多