休眠一对多映射注释问题

Posted

技术标签:

【中文标题】休眠一对多映射注释问题【英文标题】:Hibernate one to many mapping annotation issue 【发布时间】:2017-05-04 12:45:42 【问题描述】:

我是 Hibernate 的新手。我有两个表 Team(parent) 和 Product(child) 与 TEAM_ID 列作为关系,每个团队将有多个产品,每个产品将有一个团队。我在 Team 类中创建了具有 @OneToMany 映射的实体类,在 Product 类中创建了 @ManyToOne

我需要掩盖以下情况,

    在新团队时保存产品和团队 如果团队已经可用,则仅保存产品

当我尝试保存产品时,它再次尝试保存团队会引发约束错误。 请帮忙。

Team:

@Entity
@Table(name = "TEAM")
public class Team implements Serializable

private static final long serialVersionUID = 5819170381583611288L;

@Id
@SequenceGenerator(name="teamIdSeq",sequenceName="team_id_seq",allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="teamIdSeq")
@Column(name="TEAM_ID", updatable = false, nullable = false, unique = true)
private int teamId;

@Column(name="NAME", nullable = false, unique = true)
private String teamName;

@Column(name="DESCRIPTION", nullable = false)
private String teamDesc;

@Column(name="CONTACTS", nullable = false)
private String contacts;

@Column(name="APPROVER_NAME", nullable = false)
private String approverName;

@Column(name="APPROVAL_STATUS", nullable = false)
private int approvalStatus;

@Temporal(TemporalType.DATE)
@Column(name="CREATED_ON", nullable = false)
private Date createdOn;

@Column(name="CREATED_BY", nullable = false)
private String createdBy;

@Temporal(TemporalType.DATE)
@Column(name="MODIFIED_ON", nullable = false)
private Date modifiedOn;

@Column(name="MODIFIED_BY", nullable = false)
private String modifiedBy;

@OneToMany(fetch = FetchType.LAZY, mappedBy="team", cascade = CascadeType.ALL)
private Set<Product> products;

//setters and getters   


Product:

@Entity
@Table(name = "PRODUCT", uniqueConstraints = @UniqueConstraint(columnNames = "PRODUCT_ID", "TEAM_ID"))
public class Product implements Serializable

private static final long serialVersionUID = 5819170381583611288L;

@Id
@SequenceGenerator(name="productIdSeq", sequenceName="product_id_seq",allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="productIdSeq")
@Column(name="PRODUCT_ID", updatable = false, nullable = false)
private int productId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;

@Column(name="NAME", nullable = false, unique = true)
private String productName;

@Column(name="DESCRIPTION", nullable = true)
private String productDesc;

@Column(name="APPROVER_NAME", nullable = false)
private String approverName;

@Column(name="APPROVAL_STATUS", nullable = false)
private int approvalStatus;

@Temporal(TemporalType.DATE)
@Column(name="CREATED_ON", nullable = false)
private Date createdOn;

@Column(name="CREATED_BY", nullable = false)
private String createdBy;

@Temporal(TemporalType.DATE)
@Column(name="MODIFIED_ON", nullable = false)
private Date modifiedOn;

@Column(name="MODIFIED_BY", nullable = false)
private String modifiedBy;

@OneToMany(fetch = FetchType.LAZY, mappedBy="product")
private Set<Form> forms;
//setters and getters   


DAO:

@Repository
@EnableTransactionManagement
public class KMDBDAOImpl implements KMDBDAO 

@Autowired
private SessionFactory sessionFactory;

public void addTeam(Team team) 
    Product product = new Product(team, "BMA" + Math.random(), "UI Tool", "test", 
            1, new Date(), "test", new Date(), "test");
    Set<Product> products = new HashSet<Product>();
    products.add(product);
    team.setProducts(products);
    if(getTeam(team.getTeamName()) != null) 
        product.setTeam(getTeam(team.getTeamName()));
        sessionFactory.getCurrentSession().saveOrUpdate(product);
     else 
        sessionFactory.getCurrentSession().saveOrUpdate(team);
    


public Team getTeam(String teamName) 
    Query query = sessionFactory.getCurrentSession().createQuery("from Team where teamName = :name");  
    query.setString("name", "teamName");
    return (query.list().size() > 0 ? (Team) query.list().get(0) : null);

【问题讨论】:

第二种情况是简单的更新,因为数据已经存在,所以进行更新而不是新的插入 【参考方案1】:

您应该在团队中设置产品列表的唯一时间是团队是一个新实体。所以:

Set<Product> products = new HashSet<Product>();
products.add(product);
if(getTeam(team.getTeamName()) != null) 
    product.setTeam(getTeam(team.getTeamName()));
    sessionFactory.getCurrentSession().saveOrUpdate(product);
 else 
    team.setProducts(products);
    sessionFactory.getCurrentSession().saveOrUpdate(team);

【讨论】:

【参考方案2】:

我给你一些一对多关系的示例代码,请通过它,如果有问题,请告诉我..我有 2 个表 1.产品 2.sku 我的条件是,一个产品有很多 sku .

Product.java

@LazyCollection(LazyCollectionOption.FALSE)
    @ElementCollection(targetClass=Product.class)
    @OneToMany(mappedBy="product" , cascade=CascadeType.MERGE)
    private List<Sku> listSkuOrders = new ArrayList<>();

Sku.java

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = PRODUCT_ID , nullable = false)
private Product product;

【讨论】:

感谢 Y2k。根据答案,唯一的变化是级联类型从 ALL 到合并表并使用 @LazyCollection 注释。我可以知道@LazyCollection 的用法吗? gr8 .. 所以请投票给我的答案***.com/questions/12928402/…

以上是关于休眠一对多映射注释问题的主要内容,如果未能解决你的问题,请参考以下文章

休眠一对多注释外键空

使用注释一对多不添加列(休眠)

在一对多映射中使用休眠条件(以行表列作为搜索条件之一的搜索标题表)

如何使用注释在休眠中进行一对一映射

具有复合键的一对多注释映射

一对多映射创建 3 个表