title: Using embedded value objects in spring data jpa projections
body: <p>I'm working with Spring Boot 2.0RC2 and in the documentation I read you can return a projection of an entity instead of the entity as a whole when calling the Repository. This is working fine in case I use a String in my Entity but not when I use an embedded value objects.</p>
  
  <p>Let's say I have the <code>Product</code> entity:</p>
  
  <pre><code>@Entity
  @Table(name = "t_product")
  public class Product extends BaseEntity {
  
      @Column(nullable = false)
      private String name;
  
      private Product() {}
  
      private Product(final String name) {
          this.name = name;
      }
  
      public static Result&lt;Product&gt; create(@NonNull final String name) {
          return Result.ok(new Product(name));
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(@NonNull final String name) {
          this.name = name;
      }
  }
  </code></pre>
  
  <p>The <code>BaseEntity</code> simply holds the <code>id</code>, <code>created</code> and <code>updated</code> attributes.</p>
  
  <p>I have my projection interface called <code>ProductSummary</code>:</p>
  
  <pre><code>interface ProductSummary {
      String getName();
      Long getNameLength();
  }
  </code></pre>
  
  <p>And in my <code>ProductRepository</code> I have the following method that returns the <code>ProductSummary</code>:</p>
  
  <pre><code>public interface ProductRepository extends JpaRepository&lt;Product, Long&gt; {
      @Query(value = "SELECT p.name as name, LENGTH(p.name) as nameLength FROM Product p WHERE p.id = :id")
      ProductSummary findSummaryById(@Param("id") Long id);
  }
  </code></pre>
  
  <p>This works perfectly fine. Now let's say I am doing DDD and instead of using a String to represent the <code>name</code> attribute in the <code>Product</code> entity, I want to use a value object called <code>Name</code>:</p>
  
  <pre><code>@Embeddable
  public class Name implements Serializable {
  
      public static final int MAX_NAME_LENGTH = 100;
  
      @Column(nullable = false, length = Name.MAX_NAME_LENGTH)
      private String value;
  
      private Name() {}
  
      private Name(final String value) {
          this.value = value;
      }
  
      public static Result&lt;Name&gt; create(@NonNull final String name) {
          if (name.isEmpty()) {
              return Result.fail("Name cannot be empty");
          }
  
          if (name.length() &gt; MAX_NAME_LENGTH) {
              return Result.fail("Name cannot be longer than " + MAX_NAME_LENGTH + " characters");
          }
  
          return Result.ok(new Name(name));
      }
  
      public String getValue() {
          return value;
      }
  }
  </code></pre>
  
  <p>I change my <code>Product</code> entity to:</p>
  
  <pre><code>@Entity
  @Table(name = "t_product")
  public class Product extends BaseEntity {
  
      @Embedded
      private Name name;
  
      private Product() {}
  
      private Product(final Name name) {
          this.name = name;
      }
  
      public static Result&lt;Product&gt; create(@NonNull final Name name) {
          return Result.ok(new Product(name));
      }
  
      public Name getName() {
          return name;
      }
  
      public void setName(final Name name) {
          this.name = name;
      }
  }
  </code></pre>
  
  <p>And in the <code>ProductSummary</code> I change the return type from <code>String</code> to <code>Name</code>.</p>
  
  <p>When I run that I always get the exception:</p>
  
  <pre><code>Caused by: java.lang.IllegalAccessError: tried to access class com.acme.core.product.ProductSummary from class com.sun.proxy.$Proxy112
  </code></pre>
  
  <p>Can I make this work or am I missing some restriction which doesn't allow this?</p>