JPA:正确保留ManyToOne实体

时间:2015-06-19 11:01:36

标签: java hibernate java-ee jpa hibernate-mapping

我一直在寻找一个星期来修复我的问题,但没有得到任何明确的结果,尽管它似乎是一个基本问题。 如果我做错了或者我有一些误解,请告诉我。

情况如下:

用户连接到平台以进行交易。 所以我在用户和交易实体之间有多对一的关系。 (用户进行多次交易,每笔交易仅由一名用户进行)

我的想法是,当我持久保存新的“事务”时,平台当前用户的UserId将作为Transaction表的外键。

问题是:

  1. 当我尝试坚持新的“交易”时,新的“用户”也是 使用新的UserId创建。

  2. 我找不到如何正确获取要添加的当前用户的ID 它在交易表

  3. 这是我的代码:

    交易实体:

    @Entity
    public class Transaction implements Serializable{
    
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    int idTransaction;
    
    @ManyToOne(cascade=CascadeType.MERGE)
    @JoinColumn(name="FK_User")
    User    user;
    
    }
    

    用户实体:

    @Entity
    public class User implements Serializable{
    
    int idUser;
    
    @OneToMany(mappedBy="user")
    Set<Transaction>    transactions;   
    }
    

    我的方法来自ManagedBean的doTransaction:

    public String doTransaction(){
    
        String navigateTo="/pages/expediteur/succes";
    
        transaction.setExpediteur(expediteur);
        transactionServiceLocal.updateTransaction(transaction);
    
        return  navigateTo;
    }   
    

    希望我的解释清楚明白。

    *编辑*

    感谢您的帮助,我已尝试实施评论中提到的解决方案,但现在我收到此错误:

    ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-46) Cannot add or update a child row: a foreign key constraint fails 
    

    当我将这些行添加到我的代码中时:

    System.out.println("The current user is "+user.getIdUser());
    System.out.println("Your current transaction is "+user.getIdTransaction());
    

    我为所有实体获得0作为回报。

    我认为我的问题正确地存在于数据库中存储的实体中。

2 个答案:

答案 0 :(得分:1)

假设您有权访问用户ID:

public Transaction createAndPersistTransaction(Long userId) {
    // get a reference to the given user:
    User user = em.getReference(User.class, userId);
    // create a transaction
    Transaction tx = new Transaction();
    // set its user:
    tx.setUser(user);
    // persist it
    em.persist(tx);
    return tx;
}

答案 1 :(得分:0)

首先,用户应该有@Id,您可以在cascade = CascadeType.ALL方设置one-to-many

@Entity
public class User implements Serializable{

    @Id
    Integer idUser;

    @OneToMany(mappedBy="user", cascade = CascadeType.ALL)
    Set<Transaction> transactions = new HashSet()<>;   
}

现在您必须从用户界面发送userId,因此您必须先获取用户:

User user = em.getReference(User.class, userId);

您可以创建一个交易并分配关联的两面:

Transaction tx = new Transaction();
tx.setUser(user);
user.getTransactions().add(tx);
em.flush();

Transaction一旦与User实体关联,就会自动保存。