当前位置: 首页 > 知识库问答 >
问题:

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

汪理
2023-03-14

我试图在JPA中规划这种关系,但似乎在这里迷失了方向。这是我的ER型号说明。我有一个客户,其中一个客户有一个仓库,这个仓库包含股票。这就是我的想法。每个客户都有一个仓库,即(关系)1:1,仓库可以包含更多的股份(库存)。仓库--

我有以下代码。

Customer.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();
    }

}

Depot.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<>();
        }

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

使用上面的代码,我甚至可以创建并持久化客户。我是不是做错了地图?

如果我试图将数据持久化到上面的数据库中,我会收到以下错误消息。

原因:javax.persistence.PersistenceException:org.hibernate.PersistentObjectException:传递给persistent的分离实体:net.dsfinance.bank.ejb.entity.Customer

With .merge instead of persist

12:48:48,875WARN[org.hibernate.engine.jdbc.spi.SqlExceptionHelper](默认任务-46)SQL错误: 23502, SQLState:23502 12:48:48,876ERROR[org.hibernate.engine.jdbc.spi.SqlExceptionHelper](默认任务-46)NULL不允许列DEPOT_ID;SQL语句:插入客户(地址、depot_id、firstName、lastName、密码、角色、用户名、id)值 (?, ?, ?, ?, ?, ?, ?, ?)[23502-173]12:48:48,883INFO[org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl](默认任务-46)HHH000010:在批发布时,它仍然包含JDBC语句12:48:48,888WARN[com.arjuna.ats.arjuna](默认任务-46)ARJUNA012125: TwoPhaseC<--plhd完成同步失败

:javax.persistence.PersistenceException:org.hibernate.exception.ConstraintViolationException:无法执行org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)处的语句org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)org.hibernate.jpa.internal.EntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(EntityManagerImpl.java:235)org.hibernate.internal.SessionImpl.FlushBeforTransactionCompletion(SessionImpl.java:2967)在org.hibernate.engine.jdbc.internal.jdbcoordinatorimpl.beforeTransactionCompletion(SessionImpl.java:2339)在org.hibernate.engine.jdbc.internal.jdbcoordinatorimpl.beforeTransactionCompletion(jdbcoordinatorimpl.java:485)在org.hibernate.resource.transaction.backend.jta.internal.jttransactioncoordinatorimpl.beforepletion(JtaTransactionCoordinatorImpl.java:316)在org.hibernate.resource.transaction.backend.jta.internal.synchronization.SynchronizationCallbackCoordinatorContrackingImpl.完成之前(SynchronizationCallbackCoordinatorContrackingImpl.java:47)在org.hibernate.resource.transaction.backend.jta.internal.synchronization.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:37)上

原因:org.hibernate.exception.ConstraintViolationException:无法在org.hibernate.exception.internal.SqlStateConvertedLegate.convert(SqlStateConvertedLegate.java:112)的org.hibernate.exception.internal.StandardSQLExceptionConverter.converter(StandardSQLExceptionConverter.java:42)处执行语句org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)位于org.hibernate.persister.entity.AbstractEntityTypeRSister.insert(AbstractEntityTypeRSister.java:2897)处的org.hibernate.persister.entity.AbstractEntityTypeRSister.insert(AbstractEntityTypeRSister.java:2897)处的org.hibernate.persister.entity.AbstractEntity.AbstractEntityTypeRSister.insert(AbstractEntityTypeRSister.java:3397)处的在org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582)在org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456)在org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions上执行(EntityInsertAction.java:89)(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应用程序创建一个数据库,客户有一个仓库。仓库包含购买特定客户的所有股票。我如何实现这一点?谢啦

共有1个答案

齐朝明
2023-03-14

由于您没有提供用于持久化实体的代码,因此我不会对此进行详细说明(除非您编辑您的帖子),我将重点介绍解决此类问题的步骤。

首先,尝试简单,然后详细说明:从Customer类中删除depot对象,以确保您的Id生成策略正常工作。如果没有,您需要首先修复它,具体取决于您的数据库。您需要能够持久化一个简单的客户

一旦你可以持久化一个客户,向它添加一个depot(就像现在一样),没有它的共享集合。步骤与之前相同,直到您可以持久化客户及其仓库。

最后,添加共享集合,就像现在一样。在我看来,因为我不熟悉@PostConstruct注释,所以我将删除它并替换为一个普通的旧集合初始化:

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

如果以上这些都不起作用,那么显然这不再是一个映射问题了!

 类似资料:
  • 我一直试图通过一个名为Guardian的中间类映射两个用户之间的一些“OneToOne”关系。当我试图检索一个用户(和他的监护人)时,从Glassfish(Open edition V4.0)返回一个内部服务器错误。但是,日志中没有显示任何类型的堆栈跟踪或任何错误。我怀疑问题是我在JPA类中的映射。 启动服务器时,我得到两个与Guardian类有关的警告,但我并不真正理解: 警告:映射到元素[me

  • 我正在开发一个Grails应用程序。我创建了3个实体客户,产品和订单。客户可以有许多订单,但每个订单只能包含单一产品。因此,单个订单可以关联到一个客户和一个产品。以下是我的域名: 顾客: 订单: 产品: 我使用generate all生成了控制器、视图,运行应用程序时出现以下错误: 我也不能创造一个客户。域映射有什么问题吗? 我的数据源配置如下:

  • 问题内容: 这是父类Enterprise。它有雇主,其中一位是企业总裁。 这是子雇员类。它仅提供有关Enterprise的信息。但是问题是我应该使用哪种关联? 问题答案: 假设您已使用定义了-> 关联,这意味着an 仅属于一个,则应使用,意味着每个都属于max。1 ,但是可以参考很多。 您可以使用注释中的属性仅在一侧之一中定义关联细节(连接列等): 在情况下可能是一个不同的总裁,他采用(似乎不太可

  • url http://localhost:8080/authors返回此页面: url http://localhost:8080/books返回此页面: 我试图从Book类开始制作一些HTTP POST。 我有一个响应代码HTTP 204(没有内容)。如果我转到URLhttp://localhost:8080/authors/634D3BD8-ABE6-472B-97CD-04A455BDFB1

  • 我试图在我的java REST-API中映射openAPI模型(使用Swagger代码生成)和JPA实体(从HiberNate中的数据库模式生成),以便我可以使用JPA(Hibernate)实体将接收到的模型保存到数据库中,并使用模型创建从数据库中获取数据的响应。 我知道我可以分别创建使用模型和实体,并创建一种从一个转换到另一个的机制。然而,如果模型中的数据库或字段有任何变化,我需要更新模型和实体

  • 我需要记录各种业务,他们的城市和他们在每个城市的分支机构。每个企业可能在不同的城市,在每个城市可能有不同的分支机构。