0

I'm trying to store a collection of orders made by a user. One user may have many orders, but one order has only one user. So a 1-M relationship is formed. The same relationship also exists between Items and ItemOrders, an ItemOrder consits of a Item and a amount of Items to order. So, an ItemOrder has one Item but one Item can have many ItemOrders.

In my test suite I've managed to create Items and ItemOrders properly. However, when I extend the test to also create Users and Orders I get an SQLSyntaxErrorException for "Order"... This is strange as it should be the exact same procedure to achieve both outcomes... And I can't figure out what I'm doing wrong here, any ideas?

@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

@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 contains methods used primarily by BasicDao to perform CRUD operations. It has stuff like getId(), getVersion(), createVerifyIsUnqieuQuery() and so on.

BasicDao is the primary repository access class and is extended by itemsDao, UsersDao and so on. This is the relevant parts of BasicDao that is used by the test case:

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

Note that beforeInsert() is not really used by the entities used in the test.

This is the stacktrace:

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

I also tested removing BasicDao and just doing everything in one commit and i still reproduce the same error.

Tiago Redaelli
  • 560
  • 5
  • 17
  • 1
    I reproduce your entities and the test with a little spring boot application: Everything works! Your post need complements: The whole stacktrace for example. Moreover, you don't explain what is EntityInt, how is implemented BasicDao, etc. – Mohicane Oct 03 '19 at 10:03
  • Thanks for checking that part out for me. I'll look into BasicDao or see if I can find any errors in there. I've attached more parts relevant to the test as well as the causes from the stack trace. – Tiago Redaelli Oct 03 '19 at 10:48

1 Answers1

1

"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax error" Hibernate 4

The problem was that I named my table "Order" it appears. Which was gained from the stack trace above.

Tiago Redaelli
  • 560
  • 5
  • 17