title: @Formula annotation not working while retriving the persisted entity in same operation, why?
body: <p>I'm using <code>Spring + Spring Data JPA</code> example. In this using <code>@Formula</code> annotation to do some processing on data post retrieval from DB. In my project, each Entity <code>@Formula</code> annotation is meant for the different different purposes. Here I'd like to understand the concept as I dont find any useful yet.
  - Using repository <code>save()</code> method I'm persisting the entity into the DB, now in that operation only I wanted my persisted entity to be return back, while doing the entity return <code>@Formula</code> annotation not doing the job why ?   Lets see the code.</p>
  
  <p><strong>Product.java</strong></p>
  
  <pre><code>@Entity
  @Table(name = "product")
  public class Product {
  
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = "product_id")
      private Integer id;
  
      @Column(name = "product_code")
      private String productCode;
  
      @Column(name = "product_name")
      private String productName;
  
      @Column(name = "price")
      private float price;
  
      @Column(name = "vat")
      private float vat;
  
      @Formula("price * 2")
      private float totalPrice;
  
      @Column(name = "manufactured_date")
      @Temporal(TemporalType.TIMESTAMP)
      private Date manufacturedDate;
  
      public Integer getId() {
          return id;
      }
  
      public void setId(Integer id) {
          this.id = id;
      }
  
      public String getProductCode() {
          return productCode;
      }
  
      public void setProductCode(String productCode) {
          this.productCode = productCode;
      }
  
      public String getProductName() {
          return productName;
      }
  
      public void setProductName(String productName) {
          this.productName = productName;
      }
  
      public float getPrice() {
          return totalPrice;
      }
  
      public void setPrice(float price) {
          this.price = price;
      }
  
      public float getVat() {
          return vat;
      }
  
      public void setVat(float vat) {
          this.vat = vat;
      }
  
      public Date getManufacturedDate() {
          return manufacturedDate;
      }
  
      public void setManufacturedDate(Date manufacturedDate) {
          this.manufacturedDate = manufacturedDate;
      }
  
      @Override
      public String toString() {
          return "Product [id=" + id + ", productCode=" + productCode
                  + ", productName=" + productName + ", price=" + price
                  + ", vat=" + vat + ", manufacturedDate=" + manufacturedDate + "]";
      }
  }
  </code></pre>
  
  <p><strong>ProductRepository.java</strong></p>
  
  <pre><code>public interface ProductRepository extends JpaRepository&lt;Product, Integer&gt;{
      Product findByProductCode(String productCode);
  }
  </code></pre>
  
  <p><strong>ProductService.java</strong></p>
  
  <pre><code>public interface ProductService {
      void create(Product product);
      Product findByProductCode(String productCode);
  }
  </code></pre>
  
  <p><strong>ProductServiceImpl.java</strong></p>
  
  <pre><code>@Transactional
  public class ProductServiceImpl implements ProductService {
      @Autowired
      private ProductRepository productRepository;
  
      @Override
      public void create(Product product) {
          productRepository.save(product);
      }
  
      @Override
      public Product findByProductCode(String productCode) {
          return productRepository.findByProductCode(productCode);
      }
  }
  </code></pre>
  
  <p><strong>ProductTest.java</strong></p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(locations = "classpath:application-context.xml")
  public class ProductTest {
      private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
      private SimpleDateFormat SDF = new SimpleDateFormat(DATE_FORMAT);
  
      @PersistenceContext
      private EntityManager em;
  
      @Autowired
      private ProductRepository productRepository;
  
      @Autowired
      private ProductService productService;
  
      @Test
      public void testProductFinalAndGet() throws ParseException {
          Product product = new Product();
          product.setId(1);
          product.setManufacturedDate(SDF.parse("2016-08-08 10:10:15"));
          product.setPrice(400);
          product.setProductCode("AZ0111");
          product.setProductName("Nokia Lumia");
          product.setVat(5.64F);
  
          Product p = productRepository.save(product);
          System.out.println("----------------------------------------");
          System.out.println("ManufacturedDate  : "+p.getManufacturedDate());
          System.out.println("Price             : "+p.getPrice());
          System.out.println("ProductCode       : "+p.getProductCode());
          System.out.println("Product Name      : "+p.getProductName());
          System.out.println("Vat               : "+p.getVat());
      }
  
  
      @Test
      public void testFindByProductCode(){
          Product product = productService.findByProductCode("AZ00010");
          System.out.println("----------------------------------------");
          System.out.println("ManufacturedDate  : "+product.getManufacturedDate());
          System.out.println("Price             : "+product.getPrice());
          System.out.println("ProductCode       : "+product.getProductCode());
          System.out.println("Product Name      : "+product.getProductName());
          System.out.println("Vat               : "+product.getVat());
      }
  }
  </code></pre>
  
  <p>Result of testProductFinalAndGet():</p>
  
  <pre><code>Hibernate: select product0_.product_id as product_1_0_0_, product0_.manufactured_date as manufact2_0_0_, product0_.price as price3_0_0_, product0_.product_code as product_4_0_0_, product0_.product_name as product_5_0_0_, product0_.vat as vat6_0_0_, product0_.price * 2 as formula0_0_ from product product0_ where product0_.product_id=?
  Hibernate: insert into product (manufactured_date, price, product_code, product_name, vat) values (?, ?, ?, ?, ?)
  ----------------------------------------
  ManufacturedDate  : Mon Aug 08 10:10:15 IST 2016
  Price             : 0.0
  ProductCode       : AZ0111
  Product Name      : Nokia Lumia
  Vat               : 5.64
  
  
  Result of testFindByProductCode()
  
  Hibernate: select product0_.product_id as product_1_0_, product0_.manufactured_date as manufact2_0_, product0_.price as price3_0_, product0_.product_code as product_4_0_, product0_.product_name as product_5_0_, product0_.vat as vat6_0_, product0_.price * 2 as formula0_ from product product0_ where product0_.product_code=?
  ----------------------------------------
  ManufacturedDate  : 2016-03-03 00:00:00.0
  Price             : 260.0
  ProductCode       : AZ00010
  Product Name      : IPhone-New-7
  Vat               : 5.6
  </code></pre>
  
  <p>So looks like for <code>save()</code> operation, @Formula not working fine why ?  Please guide.</p>
  
  <pre><code>mysql&gt; select * from product;
  +------------+---------------------+-------+--------------+----------------+------+
  | product_id | manufactured_date   | price | product_code | product_name   | vat  |
  +------------+---------------------+-------+--------------+----------------+------+
  |         17 | 2016-03-03 00:00:00 |   130 | AZ00010      | IPhone-New-7   |  5.6 |
  |         18 | 2016-01-01 00:00:00 |   140 | AZ00011      | Lenovo Vibe X3 |  5.6 |
  |         19 | 2016-08-08 10:10:15 |   400 | AZ0111       | Nokia Lumia    | 5.64 |
  +------------+---------------------+-------+--------------+----------------+------+
  </code></pre>
  
  <p><strong>EDIT</strong>
  If I used below</p>
  
  <pre><code>@Test
      public void testProductFinalAndGet() throws ParseException {
          Product product = new Product();
          product.setId(1);
          product.setManufacturedDate(SDF.parse("2016-08-08 10:10:15"));
          product.setPrice(400);
          product.setProductCode("AZ0111");
          product.setProductName("Nokia Lumia");
          product.setVat(5.64F);
  
          Product p = productRepository.saveAndFlush(product);
          System.out.println("----------------------------------------");
          System.out.println("ManufacturedDate  : "+p.getManufacturedDate());
          System.out.println("Price             : "+p.getPrice());
          System.out.println("ProductCode       : "+p.getProductCode());
          System.out.println("Product Name      : "+p.getProductName());
          System.out.println("Vat               : "+p.getVat());
      }
  </code></pre>
  
  <p>Here is the result:</p>
  
  <hr>
  
  <pre><code>Hibernate: select product0_.product_id as product_1_0_0_, product0_.manufactured_date as manufact2_0_0_, product0_.price as price3_0_0_, product0_.product_code as product_4_0_0_, product0_.product_name as product_5_0_0_, product0_.vat as vat6_0_0_, product0_.price * 2 as formula0_0_ from product product0_ where product0_.product_id=?
  Hibernate: insert into product (manufactured_date, price, product_code, product_name, vat) values (?, ?, ?, ?, ?)
  ----------------------------------------
  ManufacturedDate  : Mon Aug 08 10:10:15 IST 2016
  Price             : 0.0
  ProductCode       : AZ0111
  Product Name      : Nokia Lumia
  Vat               : 5.64
  </code></pre>
  
  <p><strong>EDIT-2</strong></p>
  
  <hr>
  
  <p>I tried many options:</p>
  
  <pre><code>Product p = productRepository.saveAndFlush(product);
  em.refresh(p);
  </code></pre>
  
  <p>Another</p>
  
  <pre><code>Product p = productRepository.saveAndFlush(product);
  em.flush();
  em.refresh(p);
  </code></pre>
  
  <p>But getting below error:</p>
  
  <pre><code>javax.persistence.TransactionRequiredException: No transactional EntityManager available
      at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:275)
      at com.sun.proxy.$Proxy27.flush(Unknown Source)
      at com.javamakeuse.test.ProductTest.testProductFinalAndGet(ProductTest.java:62)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:497)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
      at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
      at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
      at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
      at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
      at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
      at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
  </code></pre>