繁体   English   中英

如何在3个实体之间映射oneToone和OneToMany关系?

[英]How to map oneToone and OneToMany relationship between 3 entities?

我正在尝试在JPA中编写这种关系,但是似乎在这里迷路了。 这是我的ER模型描述。 我有一个Customer ,其中一个有一个Depot ,这个Depot包含股份(股票)。 这就是我的想法。 每一个Customer都有一个Depot是(有关系)1:1和仓库可以包含更多的股票(股票)。 仓库->份额(1:m)

我有以下代码。

客户.java

@Entity
@NamedQuery(name = "Customer.getAll", query = "SELECT c FROM Customer c") 
public class Customer implements Serializable {
    private static final long serialVersionUID = 101L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id; //todo: for standard way of defining primary key

    @NotNull
    private String username;

    @NotNull
    private String firstName;

    @NotNull
    private String lastName;


    @OneToOne
    @JoinColumn(name="depot_id", nullable=false, updatable=false)
    private Depot depot;


    public Customer() {
        super();
    }

}

仓库.java

@Entity
public class Depot  implements Serializable{
    private static final long serialVersionUID = 102L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    /*@Column(name = "id", updatable = false, nullable = false)*/
    @JoinColumn(name = "customer_id")
    private Long id;


    @OneToMany(mappedBy = "tdepot")
    private List<Share> lshares;

    //todo: Total estimated value in USD
    @Transient
    private BigDecimal totalValue = new BigDecimal(0.0);


    public Depot(){
        super();
    }

    @PostConstruct
    public void init(){
        if(lshares == null){
            lshares = new ArrayList<>();
        }

    }
}

Shares.java

@Entity
public class Share implements Serializable{

    private static final long serialVersionUID = 103L;


    @Id
    protected String symbol;


    @NotNull
    protected String companyName;

    @NotNull
    protected Long floatShares;
    protected BigDecimal lastTradePrice;

    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    private java.util.Date lastTradeTime;

    @NotNull
    protected String stockExchange;


    @ManyToOne(optional=false)
    @JoinColumn(name="depot_id", nullable=false, updatable=false)
    private Depot tdepot;

    public Share(){
        super();
        lastTradeTime = new Date();
    }
}

使用上面的代码,我什至可以创建并保留一个Customer。 我做错了映射吗?

如果尝试将数据持久保存到上述数据库中,则会收到以下错误消息。 [缩短可读性]

引起原因:javax.persistence.PersistenceException:org.hibernate.PersistentObjectException:传递给持久对象的分离实体:net.dsfinance.bank.ejb.entity.Customer

With .merge instead of persist

12:48:48,875警告[org.hibernate.engine.jdbc.spi.SqlExceptionHelper](默认任务46)SQL错误:23502,SQLState:23502 12:48:48,876错误[org.hibernate.engine.jdbc.spi。 SqlExceptionHelper](默认任务46)列“ DEPOT_ID”不允许为NULL; SQL语句:将值(?,?,?,?,?,?,?,?,?)插入到Customer(地址,depot_id,firstName,lastName,密码,角色,用户名,id)中[23502-173] 12:48: 48,883 INFO [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl](默认任务46)HHH000010:在发布批处理时,它仍包含JDBC语句12:48:48,888 WARN [com.arjuna.ats.arjuna](默认任务46)ARJUNA012125:TwoPhaseCoordinator.beforeCompletion-SynchronizationImple <0:ffffc0a80869:-53b30100:5af571b4:4d,org.jboss.as.txn.service.internal.tsr.JCAOrderedLastSynchronizationList@6806

:javax.persistence.PersistenceException:org.hibernate.exception.ConstraintViolationException:无法在org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert的org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)处执行语句(org.hibernate.jpa.spi中的(AbstractEntityManagerImpl.java:1602)在org.org.hibernate.jpa.internal.EntityManagerImpl $ CallbackExceptionMapperImpl.mapManagedFlushFailure(EntityManagerImpl.java:235)在org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608) org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339)处的org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2967) 485),位于org.hibernate的org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.beforeCompletion(JtaTransactionCoordinatorImpl.java:316) .resource.transaction.backend.jta.internal.synchronization.SynchronizationCallbackCoordinatorNonTrackingImpl.beforeCompletion(SynchronizationCallbackCoordinatorNonTrackingImpl.java:47)在org.hibernate.resource.transaction.backend.jta.internal.synchronization.RegisteredSynchronization.RegisteredS

由以下原因引起:org.hibernate.exception.ConstraintViolationException:无法在org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java.org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112)处执行语句:42)在org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)在org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)在org.hibernate。 org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45)处的engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)在org.hibernate.persister.entity.AbstractEntityPersister。在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3397)在org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89)处的insert(AbstractEntityPersister.java:2897) .engi org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456)处的ne.spi.ActionQueue.executeActions(ActionQueue.java:582)org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java: 337)位于org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)位于org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)位于org.hibernate.internal.SessionImpl.managedFlush(SessionImpl .java:465),位于org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963)... 129多个原因:org.h2.jdbc.JdbcSQLException:列“ DEPOT_ID”不允许为NULL; SQL语句:

这是当我使用entitymanger.persist() ,在谷歌搜索之后,有人建议我应该使用merge但是仍然不允许我将客户添加到数据库中。

我要实现的目标:我想为一个简单的Tradingservice java EE应用程序创建一个数据库,客户拥有一个仓库。 包含购买的所有股票的仓库购买特定客户。 我该如何实现? 谢谢

由于您未提供用于保留实体的代码,因此,我不会对此进行详细说明(除非您编辑您的帖子),而我将专注于解决此类问题的步骤。

首先,尝试简单,然后进行详细说明:从Customer类中删除depot对象,以确保您的ID生成策略正常运行。 如果不是,则需要首先修复它,具体取决于您的数据库。 您需要能够保留一个简单的Customer

一旦可以保留客户,就可以向其添加一个depot (就像现在一样),而无需收集其shares 与之前相同的步骤,直到您可以保留客户及其仓库。

最后,添加shares集合,就像现在一样。 IMO,因为我不熟悉@PostConstruct批注,因此将其删除并替换为简单的旧集合初始化:

private List<Share> lshares = new ArrayList<>();

如果以上方法均无效,则显然不再是映射问题!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM