无法为第二种情况映射OneToMany和ManyToOne吗?

时间:2019-10-03 09:27:12

标签: java hibernate

我正在尝试存储用户所下订单的集合。一个用户可能有很多订单,但是一个订单只有一个用户。这样就形成了1-M关系。在Item和ItemOrders,一个ItemOrder包含一个Item和要订购的Item数量之间也存在相同的关系。因此,一个ItemOrder具有一个Item,但是一个Item可以具有多个ItemOrders。

在我的测试套件中,我设法正确创建了Items和ItemOrders。但是,当我将测试扩展为还创建用户和订单时,我得到了“订单”的SQLSyntaxErrorException……这很奇怪,因为它应该是完全相同的过程才能实现两个结果……而且我不知道该怎么办我在这里做错了,有什么想法吗?

@Entity
public class ItemEntity implements EntityInt {
    @Id
    @GeneratedValue(generator = "incrementor")
    @Column(name = "item_id", unique = true)
    public int id;

    @OneToMany(mappedBy="item")
    public Set<OrderItemEntity> orderItems = new HashSet<>();

}

@Entity
public class OrderItemEntity implements EntityInt {

    @Id
    @GeneratedValue(generator = "incrementor")
    @Column(name = "order_item_id", unique = true)
    public int id;

    @Column(name = "amount", nullable = false)
    public int amount;

    @ManyToOne
    @JoinColumn(name="item_id", nullable = false)
    private ItemEntity item;

    public OrderItemEntity(ItemEntity item, int amount) {
        this.setItem(item);
        this.amount = amount;
    }

    public void setItem(ItemEntity item) {
        if (this.item != null)
            this.item.orderItems.remove(this);
        this.item = item;
        this.item.orderItems.add(this);
    }
}

@Entity
public class OrderEntity implements EntityInt {

    @Id
    @GeneratedValue(generator = "incrementor")
    @Column(name = "order_id", unique = true)
    public int id;

    @ManyToOne
    @JoinColumn(name="user_id", nullable = false)
    public UserEntity user;

    public UserEntity getUser() {
        return user;
    }

    public void setUser(UserEntity user) {
        if (this.user != null)
            this.user.orders.remove(this);
        this.user = user;
        this.user.orders.add(this);
    }
}

@Entity
public class UserEntity implements EntityInt {

        @Id
        @GeneratedValue(generator = "incrementor")
        @Column(name = "user_id", unique = true)
        public int id;

        @OneToMany(mappedBy="user")
        public Set<OrderEntity> orders = new HashSet<>();

}

测试

@Test
    public void testItemOrderEntity() throws Exception {
         EntityManagerFactory factory = BasicDao.getEntityManagerFactory();
    EntityManager em = factory.createEntityManager();

    em.getTransaction().begin();

    String itemName = Math.random() + "";
    ItemEntity item = new ItemEntity(itemName, 0, 0);
    em.persist(item);

    OrderItemEntity orderItem = new OrderItemEntity(item, 5);
    em.persist(orderItem);

    String uname = "" + Math.random();
    UserEntity user = new UserEntity(uname, uname);
    em.persist(user);

    // Error
    OrderEntity order = new OrderEntity(user);
    em.persist(order);
    em.getTransaction().commit();
    }

EntityInt包含BasicDao主要用于执行CRUD操作的方法。它具有诸如getId(),getVersion(),createVerifyIsUnqieuQuery()之类的东西。

BasicDao是主要的存储库访问类,并由itemsDao,UsersDao等扩展。这是测试用例使用的BasicDao的相关部分:

BasicDao.java

private static final String PERSISTENCE_UNIT_NAME = "org.hibernate.lab1_web_shop.jpa";

    public static EntityManagerFactory getEntityManagerFactory() {
        return  Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    }

    public static EntityInt insert(EntityInt entity) throws Exception {
        EntityManagerFactory factory = getEntityManagerFactory();
        EntityManager em = factory.createEntityManager();
        try {
            em.getTransaction().begin();
            Query isUniqueQuery = entity.createVerifyIsUniqueQuery(em);
            if (isUniqueQuery != null) {
                List<EntityInt> resultList = isUniqueQuery.getResultList();
                if (resultList.size() == 0) {
                    entity.beforeInsert(em);
                    em.persist(entity);
                } else {
                    entity = null;
                }
            } else {
                // There is no uniqueness filter so we insert it as is
                entity.beforeInsert(em);
                em.persist(entity);
            }
            em.getTransaction().commit();
            // Returns the persistent entity along with any database modified attributes
            return entity;
        } catch (Exception e) {
            em.getTransaction().rollback();
            throw new Exception(e);
        } finally {
            em.close();
        }
    }

请注意,测试中使用的实体并未真正使用beforeInsert()。

这是堆栈跟踪:

Caused by: javax.persistence.RollbackException: Error while committing the transaction
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute statement
Caused by: org.hibernate.exception.SQLGrammarException: could not execute statement
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Order (user_id, version, order_id) values (9, 0, 10)' at line 1

我还测试了删除BasicDao并在一次提交中完成所有操作,但我仍然会再现相同的错误。

1 个答案:

答案 0 :(得分:1)