1 Reply Latest reply on Nov 1, 2006 4:23 AM by wolfgangknauf

    merge one-to-one strategy

    lpiccoli

      hi all,

      I am having troubles understanding the EJB3 updating strategy. I am familar with the traditional mechanism of dealing with just FK when updating a one-to-one relationship. However with EJB3 the FK is now a object.
      From the EJB3trail there is a example that does the following for a persist.
      It loads both foreign key objects before setting, then persisting.

      public double calculate (int fundId, int investorId, double saving) {
      26
      27 Investor investor =
      28 em.find(Investor.class,
      29 Integer.valueOf(investorId));
      30 Fund fund =
      31 em.find(Fund.class,
      32 Integer.valueOf(fundId));
      33
      34 int start = investor.getStartAge();
      35 int end = investor.getEndAge();
      36 double growthrate = fund.getGrowthrate();
      37
      38 double tmp = Math.pow(1. + growthrate / 12., 12. * (end - start) + 1);
      39 double result = saving * 12. * (tmp - 1) / growthrate;
      40 Timestamp ts = new Timestamp (System.currentTimeMillis());
      41
      42 TimedRecord rec =
      43 new TimedRecord (fund, investor, saving, result, ts);
      44 em.persist (rec);
      45
      46 return result;
      47 }
      


      Is the same mechanism required when updating?
      Unfortunetly the EJB3trail does not have a one-to-one merge example.
      Is something like the following performant or are there better mechanisms?
      The major issue is executing the load of the FK relationship object. Which seems expensive when i already have the FK id.


      
      strategy 1
      
      public double update (int recId, int fundId, int investorId, double saving) {
      
       Investor investor =
       em.find(Investor.class,
       Integer.valueOf(investorId));
       Fund fund =
       em.find(Fund.class,
       Integer.valueOf(fundId));
       TimeRecord rec =
       em.find(Fund.class,
       Integer.valueOf(fundId));
      
       rec.setSaving( saving);
       rec.setFund( fund );
       rec.setInvestor( investor );
       em.merge (rec);
      
       return result;
       }
      



      I have tried the following with little success as it complains about transient Objects



      
      strategy 2 not working.
      
      public double update2 (int recId, int fundId, int investorId, double saving) {
      
       Investor investor =new Investor( investorId);
       Fund fund = new Fund( fundId);
       TimeRecord rec =
       em.find(Fund.class,
       Integer.valueOf(fundId));
      
       rec.setSaving( saving);
       rec.setFund( fund );
       rec.setInvestor( investor );
       em.merge (rec);
      
       return result;
       }
      
      


      So my question is does the merge on one-to-one relationship require fullly populated detached objects or can it be done with just the id for the FK?

      many thanks

      -lp


        • 1. Re: merge one-to-one strategy
          wolfgangknauf

          Hi,

          I think you have to modify both sides of the relationship (if it is bidirectional):

          E.g in your strategy 2:

          public double update2 (int recId, int fundId, int investorId, double saving) {
          
           Investor investor =new Investor( investorId);
           Fund fund = new Fund( fundId);
           TimeRecord rec =
           em.find(Fund.class,
           Integer.valueOf(fundId));
          
           rec.setSaving( saving);
           saving.setTimeRecord (rec);
           rec.setFund( fund );
           fund.setTimeRecord (rec);
           rec.setInvestor( investor );
           investor.setTimeRecord (rec);
           em.merge (rec);
          
           return result;
           }