2

I am trying to insert data into a table having columns (NAME, VALUE) with

EntityManager.persist().

When I persist an entity like ('xx', 'value1') it inserts a new record into the table for that entity. But if I want to persist a new entity like ('xx', 'value2'), the entity is persisted in the place of already existing record.

The questions are:

  • Why and how is it happened?
  • Is there a way to insert ('xx', 'value2') too?

I found a similar question here but there is no real answer for the question.

Many thanks.

UPDATE: The first column is not a primary key. Instead, the second one is.

Here is the Entity:

@Entity
@Table(name = "TEST_DATA")
public class TestDataEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name = "NAME", nullable = false)
    private String name;

    @Id
    @Column(name = "VALUE", nullable = false)
    private String value;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

And here is the persisting code:

@Transactional
public static void storeTestData(EntityManager em, String name, String value) {
    TestDataEntity entity = new TestDataEntity();
    entity.setName(name);
    entity.setValue(value);

    em.persist(entity);
}

Also, there is another question, which is described here.

Community
  • 1
  • 1
Armine
  • 1,675
  • 2
  • 24
  • 40
  • columns are primary keys, not values – bichito Apr 11 '17 at 13:34
  • @Armine: So when you first call `storeTestData(entityManager, "xx", "value1");` and then `storeTestData(entityManager, "xx", "value2");` it actually overrides the primary key of the previously persisted entity and changes it to "value2"? That is indeed weird and i have no explanation of why it happens. – OH GOD SPIDERS Apr 11 '17 at 14:03
  • @OHGODSPIDERS: Yes, it is exactly as you described. And that's why I couldn't understand the reason :(. – Armine Apr 11 '17 at 14:05

2 Answers2

1

The issue is solved this way:

@Transactional
public static void storeTestData(EntityManager em, String name, String value) {
    EntityTransaction transaction = em.getTransaction();

    try {
        transaction.begin();

        TestDataEntity entity = new TestDataEntity();
        entity.setName(name);
        entity.setValue(value);

        em.persist(entity);

        transaction.commit();
    } catch (RuntimeException re) {
        if (transaction != null && transaction.isActive())  {
            transaction.rollback();
        }

        throw re;
    }

This means, that if no explicit transaction is provided, then the existing record is being updated if it has any value matched with the corresponding field value in entity object.

IMHO, this is really strange and not straightforward, since it would be better if it would throw a

javax.persistence.TransactionRequiredException

like it does on update/delete statements.

Armine
  • 1,675
  • 2
  • 24
  • 40
0

Check if your entity correctly implements equals() and hashCode(), usually this solves the problem

  • Actuallly, I didn't overloaded none of these methods, consequently, both entities shouldn't be equal, right? – Armine Apr 11 '17 at 13:40
  • @Armine Are you creating the Entity and its contents new via constructor every time? If you just modify an already exiting and persited entity and then try to persist it again this could be the problem. Otherwise its hard to tell whats going on without you providing some example of your Entity Class code and how you persist it. – OH GOD SPIDERS Apr 11 '17 at 13:45
  • @OHGODSPIDERS: Please take a look to the updated question. I do create the entity each time via new constructor. – Armine Apr 11 '17 at 13:58