2017-05-04 76 views
1

我是Hibernate的新手。我有兩個表Team(父母)和Product(子女)與TEAM_ID列作爲關係,每個團隊將有多個產品,每個產品將有單個團隊。我已經創建了實體類,其中@OneToMany在Team類中映射,@ManyToOneProduct類中映射。休眠一對多映射註解問題

我需要掩飾下面的場景,

  1. 爲了節省產品和團隊,當團隊是新
  2. 僅保存的產品,如果球隊已經可用

當我試圖它保存的產品嚐試再次保存團隊拋出約束錯誤。 請幫忙。

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); 
} 
+0

第二種情況是一個簡單的更新數據ALRE ady存在,所以進行更新而不是新插入 – akuma8

回答

0

您應該在Team上設置產品列表的唯一時間是Team是新實體的時候。所以:

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); 
} 
+0

謝謝Maciej。我會試一試並更新你 – user3800354

0

我給你一個了一些示例代碼,以一對多的關係,請通過它,讓我千牛,如果一些問題....我有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; 
+0

謝謝Y2k。根據答案,只有更改是從ALL級聯類型到合併表並使用@LazyCollection註釋。我可以知道@LazyCollection的用法嗎? – user3800354

+0

gr8 ..所以請投我的答案http://stackoverflow.com/questions/12928402/what-is-the-use-of-the-hibernate-lazycollection-annotation – y2k