Search code examples
javaspringjparepository

Get data from a repository using Spring


Ok so I am new to spring and don't really know how this works. I have been trying a few things and think its close to doing it but not getting any data from the server and giving me this error

 Unsatisfied dependency expressed through constructor argument with index 4 of type [jp.co.fusionsystems.dimare.crm.service.impl.MyDataDefaultService]: : Error creating bean with name 'MyDataDefaultService' defined in file  

My end point

//mobile data endpoint
 @RequestMapping(
        value = API_PREFIX + ENDPOINT_MyData + "/getMyData",
        method = RequestMethod.GET)
public MyData getMyData() {
    return MyDataDefaultService.getData();
}

My Object

public class MyData {

public MyData(final Builder builder) {
    videoLink = builder.videoLink;
}
private String videoLink;

public String getVideoLink()
{
    return videoLink;
}

public static class Builder
{
    private String videoLink = "";  

    public Builder setVideo(String videoLink)
    {
        this.videoLink = videoLink;
        return this;
    }

    public MyData build()
    {
        return new MyData(this);
    }

}
 @Override
    public boolean equals(final Object other) {
        return ObjectUtils.equals(this, other);
    }

    @Override
    public int hashCode() {
        return ObjectUtils.hashCode(this);
    }

    @Override
    public String toString() {
        return ObjectUtils.toString(this);
    }

    }

The Repository

 public classMyServerMyDataRepository implements MyDataRepository{

private finalMyServerMyDataJpaRepository jpaRepository;
private final MyDataConverter MyDataConverter = new MyDataConverter();

@Autowired
publicMyServerMyDataRepository(finalMyServerMyDataJpaRepository jpaRepository) {
    this.jpaRepository = Validate.notNull(jpaRepository);
}


@Override
public MyData getData() {
    MyDataEntity entity = jpaRepository.findOne((long) 0);
    MyData.Builder builder = new MyData.Builder()
            .setVideo(entity.getVideoLink());

    return builder.build();
}

The DefaultService that gets called by the endpoint

 public class MyDataDefaultService {
private static final Logger logger =      LoggerFactory.getLogger(NotificationDefaultService.class);

private finalMyServerMyDataRepository repository;

@Autowired
public MyDataDefaultService(MyServerMyDataRepository repository) {
    this.repository = Validate.notNull(repository);
}


//Get the data from the server
public MobileData getData()
{
    logger.info("Get Mobile Data from the server");
    //Get the data from the repository
    MobileData mobileData = repository.getData();

    return mobileData;

}
 }

The Converter

 public class MyDataConverter  extends AbstractConverter<MyDataEntity, MyData>
 {

@Override
public MyData convert(MyDataEntity entity) {

    MyData.Builder builder = new MyData.Builder()
            .setVideo(entity.getVideoLink());
    return builder.build();
}

 }

My Entity

 @Entity
 @Table(name = “myServer”)
 public class MyDataEntity extends AbstractEntity{
 @Column(name = "video_link", nullable = true)
    private String videoLink;

 public String getVideoLink() {
        return videoLink;
    }

    public void setVideoLink(final String videoLink) {
        this.videoLink = videoLink;
    }

}

Thank you for any help with this


Solution

  • Hibernate entity should have default constructor defined and implement Serializable interface as well, assume AbstractEntity matches the requirement. Hibernate won't accept an entity without a primary key so you have to define the one too:

     @Entity
     @Table(name = “myServer”)
     public class MyDataEntity implements Serializable {
    
        @Id
        @GeneratedValue
        private Long id;
    
        @Column(name = "video_link", nullable = true)
        private String videoLink;
    
        public MyDataEntity() {
    
        }
    
        ...setters&getters
    }
    

    MyData object represents the JSON server response, you can use Jackson annotations to control the result JSON properties:

    public class MyDataResponse {
    
        @JsonProperty("video_link")
        private String videoLink;
    
        public MyDataResponse() {
    
        }
    
        public MyDataResponse(String videoLink) {
            this.videoLink = videoLink;
        }
    
        ...setters&getters
    }
    

    Spring has an awesome project so called Spring Data that provides the JPA repositories, so there's no even the @Repository annotation ever needed:

    public class MyDataRepository extends CrudRepository<MyDataEntity, Long> {
    
    }
    

    The Builder class represents the Service layer:

    @Service
    public class MyDataService {
    
        @Autowired
        private MyDataRepository myDataRepository;
    
        public MyDataResponse getMyData(Long id) {
            
            MyDataEntity entity = myDataRepository.findOne(id);
            ...rest logic, copy necessary data to MyDataResponse
        } 
    }
    

    Then a controller is:

    @RestController // @ResponseBody not needed when using like this
    public MyDataController {
    
        @Autowired
        private MyDataService myDataService;
    
        @RequestMapping("/getMyData") // no need to specify method for GET
        public MyDataResponse getMyData(@RequestParam("ID") Long myDataId) {
        
                ... validation logic
        
                return myDataService.getMyData(myDataId); // return response
        }
    }
    

    Now it should work, don't forget to add required dependencies to your classpath.