【问题标题】:JPA: Persisting ManyToOne entities correctlyJPA:正确地持久化多对一实体
【发布时间】:2015-09-05 08:09:33
【问题描述】:

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

情况如下:

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

这个想法是,当我持久化一个新的“事务”时,平台当前用户的 UserId 作为事务表的外键。

问题是:

  1. 当我尝试持久化一个新的“事务”时,一个新的“用户”也是 使用新的 UserId 创建。

  2. 我没有找到如何正确获取要添加的当前用户的 ID 它在事务表中

这是我的代码:

交易实体:

@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;   
}

我的方法 doTransaction 来自 ManagedBean:

public String doTransaction(){

    String navigateTo="/pages/expediteur/succes";

    transaction.setExpediteur(expediteur);
    transactionServiceLocal.updateTransaction(transaction);

    return  navigateTo;
}   

希望我的解释清楚而简短。

* 编辑 *

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

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。

我认为我的问题是正确处理数据库中存储的实体。

【问题讨论】:

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


    【解决方案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;
    }
    

    【讨论】:

    • 感谢您的帮助,我已尝试实施 cmets 中提到的解决方案,但现在我收到此错误:ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper](默认task-46) 无法添加或更新子行:外键约束失败,当我将这些行添加到我的代码时: System.out.println("当前用户是 "+user.getIdUser()); System.out.println("你当前的交易是"+user.getIdTransaction());作为回报,我得到所有实体的 0。我认为我的问题是正确处理数据库中存储的实体。
    【解决方案2】:

    首先,用户应该有一个@Id,你可以在one-to-many一侧设置cascade = CascadeType.ALL):

    @Entity
    public class User implements Serializable{
    
        @Id
        Integer idUser;
    
        @OneToMany(mappedBy="user", cascade = CascadeType.ALL)
        Set<Transaction> transactions = new HashSet()<>;   
    }
    

    现在你必须有一个从 UI 发送的userId,所以你必须先获取用户:

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

    您可以创建一个事务并分配关联的双方:

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

    TransactionUser 实体关联后,将自动保存。

    【讨论】:

    • 感谢您的帮助,我已尝试实施 cmets 中提到的解决方案,但现在我收到此错误:ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper](默认task-46) 无法添加或更新子行:外键约束失败,当我将这些行添加到我的代码时: System.out.println("当前用户是 "+user.getIdUser()); System.out.println("你当前的交易是"+user.getIdTransaction());作为回报,我得到所有实体的 0。我认为我的问题是正确处理数据库中存储的实体。
    猜你喜欢
    • 2012-12-17
    • 2011-07-16
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多