0

The below code seem simple, yet it takes me long time but turned out to be cumbersome and lengthy code even i dislike. could someone help me with some efficient code? many thanks. by the way, i'm using hibernate 3.6 JPA implementation

@Entity
class X
{
     @OneToMany( fetch = FetchType.EAGER, mappedBy = "x", cascade = { CascadeType.PERSIST, CascadeType.MERGE } )
     private Set<Y> ys = new HashSet<Y>();

     public void persist()
     {
        //here, this(x) is newly create but its ys are already in the DB, so how to write the code?
     }

     public void merge()
     {
       //like persist(), the ys of this(x) is changed, how to merge effiently?
     }

}

i use the below but it will throw exception: Cannot fetch unpersisted entity

     public void merge()
     {
             EntityManager em = entityManager();
             EntityTransaction tx = em.getTransaction();
             try
             {
               tx.begin();
               for(Y y: ys)
                  em.merge(y);
               em.merge(this);
               tx.end();
             }
             finally
             {
                ...
             }
      }
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
Mike
  • 3,515
  • 10
  • 44
  • 67

3 Answers3

2
  1. You can use merge() for persisting new entities.
  2. Note that merge() returns a merged entity that may be not the same as an entity passed in.

See also:

Community
  • 1
  • 1
axtavt
  • 239,438
  • 41
  • 511
  • 482
1

Per spec merge can be used as for persist purposes as for updating. The decision is making on presence of @Id value. So JPA itself provide most efficient way to store your entity

Dewfy
  • 23,277
  • 13
  • 73
  • 121
0

You don 't call EntityManagers functions in the entities. You would create a new X and add the Y's to it. Calling EntitiManager.persist() in the end.

X x = new new X();
for(Y y : findSomeYsilons() ) {
   x.add(y);
}
em.persist(x);

Your entities should not know about JPA / Hibernate / Transactions.

bert
  • 7,566
  • 3
  • 31
  • 47
  • As long as it's within the scope of a transaction, it makes no difference where you use an EM. – Jeremy Jul 24 '11 at 02:11
  • @Jeremy Heiler why a down vote? While it is technically correct to call an EM in the entities, it is considered a bad practice. Besides, my answer was correct, even if it was not the one he was looking for? – bert Jul 24 '11 at 19:11
  • I down-voted because you didn't explain why you think it's a bad practice to use an EM inside an entity. [ActiveRecord](http://en.wikipedia.org/wiki/ActiveRecord) is a viable [design pattern](http://martinfowler.com/eaaCatalog/activeRecord.html). One example of its use in Java is with the [Play! Framework](http://www.playframework.org/). (I'm not defending the OP's implementation of it, though. I agree that *transactions* shouldn't be seen inside an entity, as that is, by design, part of a broader scope. Usually.) – Jeremy Jul 25 '11 at 18:26
  • Because something is technically possible this doesn't necessary make it a good practice. The design principle that someone should have in mind is called "Separation of Concerns". So far it is never a good idea to mix simple enities and persistence implementation into one class. – magomi Jul 25 '11 at 19:11
  • @magomi: I have sourced from a very respected software developer that the ActiveRecord pattern *actually is* a good practice. I've also sourced a successful framework that uses it. (I didn't even mention Rails...) But, that doesn't mean it is the *only* good practice, just *one* of them. If you want to blindly follow a **single** good practice, that's your call. Basic [OO principles state that objects should encapsulate data and functionality](http://en.wikipedia.org/wiki/Object-oriented_programming). Separation of concerns is relative. It depends on what you are concerned about. – Jeremy Jul 26 '11 at 00:50
  • @Jeremy Heiler thats all good and fine and I welcome the discussion about this. My concern was about the downvote. Just because I think there are other possible solutions does not mean I have to downvote them, don 't you think? – bert Jul 26 '11 at 09:31
  • @bert: I'm sorry. I didn't think this would matter so much. I didn't think your answer was adequate or even pertained to the question (well, the code did, but the comments did not), and that's why I down voted. I'll return your Internet Points if you edit your question, otherwise SO wont let me. – Jeremy Jul 26 '11 at 17:57
  • @Jeremy - sorry, maybe I was not clear enough. Sure there are cases when it is fine to bundle data objects and the persistence functions into one object. But the OP talked explicitly about JPA and my practice tells me that is not ok to mix the persistence functions into the entity objects when you use JPA. You named the play framework. Also in play framework your entity implementation has no code for persistence. These functionality is inherited from the Model class. This makes a big difference - expecially in comparison to the OPs code. – magomi Jul 28 '11 at 16:14
  • @magomi: Fair enough. Although, semantically from a client's POV (someone who uses the entities) it's the same. The major design difference is *who* does the CRUD. That is, the entity itself or a third party. Getting deeper into a proper implementation, yes, a superclass such as Model would do the most of the work, but that doesn't really change the semantics of it all. – Jeremy Jul 29 '11 at 12:49