2013/12/19

JPA entity status など

New (transient): an entity is new if it has just been instantiated using the new operator, and it is not associated with a persistence context. It has no persistent representation in the database and no identifier value has been assigned.

    Managed (persistent): a managed entity instance is an instance with a persistent identity that is currently associated with a persistence context.

    Detached: the entity instance is an instance with a persistent identity that is no longer associated with a persistence context, usually because the persistence context was closed or the instance was evicted from the context.

    Removed: a removed entity instance is an instance with a persistent identity, associated with a persistence context, but scheduled for removal from the database.

The EntityManager API allows you to change the state of an entity, or in other words, to load and store objects. You will find persistence with JPA easier to understand if you think about object state management, not managing of SQL statements.


★javaX EitheManager persist merge

Either way will add an entity to a PersistenceContext, the difference is in what you do with the entity afterwards.

Persist takes an entity instance, adds it to the context and makes that instance managed (ie future updates to the entity will be tracked)

Merge creates a new instance of your entity, copies the state from the supplied entity, and makes the new copy managed. The instance you pass in will not be managed (any changes you make will not be part of the transaction - unless you call merge again).

SomeClass javax.persistence.EntityManager.merge(SomeClass arg0)
==>you can get the object after insert

Maybe a code example will help.

MyEntity e = new MyEntity();

// scenario 1
// tran starts
em.persist(e);
e.setSomeField(someValue);
// tran ends, and the row for someField is updated in the database

// scenario 2
// tran starts
e = new MyEntity();
em.merge(e);
e.setSomeField(anotherValue);
// tran ends but the row for someField is not updated in the database (you made the changes *after* merging

// scenario 3
// tran starts
e = new MyEntity();
MyEntity e2 = em.merge(e);
e2.setSomeField(anotherValue);
// tran ends and the row for someField is updated (the changes were made to e2, not e)



★Detaching a object

An object when loaded in the persistence context is managed by Hibernate. You can force an object to be detached (ie. no longer managed by Hibernate) by closing the EntityManager or in a more fine-grained approach by calling the detach() method.

Cat cat = em.find( Cat.class, new Long(69) );
...
em.detach(cat);
cat.setName("New name"); //not propatated to the database



★SomeObject object=new SomeObject();
object.setId(1);
object.setColumn1("");
entityManager.persist();
----->エラーになった。。detached entity passed to persist

This is because Hibernate thinks that this object was returned from the Entity Manager since it has a primary key assigned. One way to solve this is by using a merge() function. This is the default way that Spring Roo does it.



★Hibernate: “Field 'id' doesn't have a default value”
ーー>SOLVED: recreating the database solved the problem
---->何?説明しろ
If you want MySQL to automatically produce primary keys then you have to tell it when creating the table. You don't have to do this in Oracle.
ーーー>たしかに"AUTO_INCREMENT "されていないね。。。。。。