6 Replies Latest reply on Feb 26, 2016 2:59 AM by Martin Kouba

    Weld injects a proxy instead of real instance - why?

    moritz l Newbie

      In my application i have "@RequestScoped" converter classes that convert jpa entities to jaxb classes (dto serialized to json) and vice versa. All of those classes inject Provider<JaxbClass>. I need to use the provider because those Jaxb-classes extend a class that itself injects some stuff. This all works fine: the provider produces real instances. The class hierarchy looks like that:

       

      interface Identifiable (getId) -> abstract class Linkable (injects some stuff) -> jaxb-class (annotated with xmlroot)

       

      Some classes also extend an additional abstract class (createBy) that provides an additional field, also here no problem.

      The problem begins if i create an Jaxb-classes from an generic abstract class (don't know if this is related to problem). The hierarchy is:

       

      [hierarchy as before]->abstract class<T>->jaxb-class

       

      if i try to get an instance via a provider of those classes the instance is a weld proxy. This proxy has additional fields and the json (un)marshaller moans about unknown field (handler), it can't handle it. My question is why in the latter case i get an proxy?

       

      Here is a working example:

      Converter

      @RequestScoped
      public class VendorRepresentationConverter extends RepresentationConverter.Base<VendorRepresentation,Vendor> {
      
          @Inject
          @CurrentUser
          private User user;
      
          @Inject
          private Provider<VendorRepresentation> vrProv;
      
          @Inject
          private UserRepresentationConverter userReprsentationConverter;
          @Override
          protected Vendor createNew(VendorRepresentation representation) {
              return new Vendor(representation.getName(), representation.getHomePage(), user);
          }
      
          @Override
          public VendorRepresentation from(Vendor vendor) {
              VendorRepresentation vendorRepresentation = vrProv.get(); //returns real instance
              vendorRepresentation.setName(vendor.getName());
              vendorRepresentation.setHomePage(vendor.getHomePage());
              vendorRepresentation.setCreatedBy(userReprsentationConverter.from(vendor.getCreatedBy()));
              vendorRepresentation.setId(vendor.getId());
              return vendorRepresentation;
          }
      
        @Override
          public Vendor update(VendorRepresentation representation, Vendor target) {
              target.setName(representation.getName());
              target.setHomePage(representation.getHomePage());
              return target;
          }
      }
      
      
      

       

      jaxb class:

      @XmlRootElement(name = "vendor", namespace = "urn:problems:vendor")
      public class VendorRepresentation extends CreatedByUserRepresentation{
      
        @NotNull
          private String name;
      
          @NotNull
          private String homePage;
      
          @Override
          protected Class<?> getResourceClass() {
              return VendorResource.class;
          }
      
      
          public String getName() {
              return name;
          }
      
        public void setName(String name) {
              if(Strings.isNullOrEmpty(name)){
                  throw new IllegalArgumentException("Name must neither null nor empty.");
              }
              this.name = name;
          }
      
          public String getHomePage() {
              return homePage;
          }
      
          public void setHomePage(String homePage) {
              if(Strings.isNullOrEmpty(homePage)){
                  throw new IllegalArgumentException("Home page must neither null nor empty.");
              }
              this.homePage = homePage;
          }
      
      
      
      

      now the non working example

       

      converter

      @RequestScoped
      public class ProblemVoteRepresentationConverter extends VoteRepresentationConverter<ProblemVoteRepresentation, ProblemVote> {
      
          @Inject
          private ProblemRepresentationConverter problemConverter;
      
          @Inject
          private Provider<ProblemVoteRepresentation> problemVoteRepresentationProvider;
      
          @Override
          protected ProblemVote createNew( ProblemVoteRepresentation representation ) {
              return new ProblemVote( problemConverter.to( representation.getVoteOf() ), representation.getValue()==1, user );
          }
      
          @Override
          public ProblemVoteRepresentation from( ProblemVote problemVote ) {
              ProblemVoteRepresentation problemVoteRepresentation = problemVoteRepresentationProvider.get(); //proxy is provided!!!!!!!!!!!!!!!
              problemVoteRepresentation.setVoteOf(problemConverter.from(problemVote.getEntity()));
              problemVoteRepresentation.setValue(problemVote.getValue());
              problemVoteRepresentation.setCreatedBy(userConverter.from( problemVote.getCreatedBy()));
              problemVoteRepresentation.setId( problemVote.getId());
              return problemVoteRepresentation;
          }
      }
      
      
      

      based on

      @RequestScoped
      public abstract class VoteRepresentationConverter<REST extends Identifiable, SOURCE> extends RepresentationConverter.Base<REST, SOURCE>{
      
          @Inject
          @CurrentUser
          protected User user;
      
          @Inject
          protected UserRepresentationConverter userConverter;
      
          @Override
          public SOURCE update(REST representation, SOURCE target) {
              throw new UnsupportedOperationException("Votes can't be updated.");
          }
      }
      
      
      

       

      jaxb:

      @XmlRootElement(name = "problemvote", namespace = "urn:problems:problemvote")
      public class ProblemVoteRepresentation extends VoteRepresentation<ProblemRepresentation> {
      
          @Override
          protected Class<?> getResourceClass() {
              return ProblemVoteResource.class;
          }
      }
      
      
      

      based on:

      public abstract class VoteRepresentation<T extends CreatedByUserRepresentation> extends CreatedByUserRepresentation{
      
          @NotNull
          private T voteOf;
      
          @Min(-1) // down vote
          @Max(1) // up vote
          private int value;
      
          @AssertTrue
          public boolean valueIsNotZero() {
              return value != 0;
          }
      
          public T getVoteOf() {
              return voteOf;
          }
      
          public int getValue() {
              return value;
          }
      
          public void setVoteOf(T voteOf) {
              this.voteOf = voteOf;
          }
      
          public void setValue(int value) {
              this.value = value;
          }
      
      }
      
      
      

       

      now the hierarchy continues like in the working example. So what could possibly cause weld to provide a proxy instead of real instance of "ProblemVoteRepresentation" ?