8

I have a simple model, instances of which I want to save in MySQL using Spring JDBCTemplate. I use DAO that saves model objects using simple sql (insert into user(id, email...) value (:id, :email...)). Is there any framework that can extract parameters from the model (when the model is just POJO with public fields). So, I need something similar to Spring's BeanPropertySqlParameterSource, but with the ability to work with public fields instead of properties.

Example of the model class:

public class User {
    public int id;
    public String email;
    public String login;
    public String password;
}

I know that extending AbstractSqlParameterSource can solve my problem, but I hope to find existing framework.

UPD

Implementation based on AbstractSqlParameterSource:

public class PublicFieldsSqlParameterSource extends AbstractSqlParameterSource {

    Map<String, Object> props = new HashMap<>();

    public PublicFieldsSqlParameterSource(Object object) {
        Field[] fields = object.getClass().getFields();
        for (Field field : fields) {
            String name = field.getName();
            try {
                Object value = field.get(object);
                props.put(name, value);
            } catch (IllegalAccessException ignored) {
            }
        }
    }

    @Override
    public boolean hasValue(String paramName) {
        return props.containsKey(paramName);
    }

    @Override
    public Object getValue(String paramName) throws IllegalArgumentException {
        return props.get(paramName);
    }
}
Ernest Sadykov
  • 831
  • 8
  • 28
  • The existing framework is called JavaBeans. Add public accessors for your fields and then you'll be able to use libraries naturally. That is the purpose of coding conventions. – Yosef Weiner Aug 02 '15 at 18:23
  • @SkinnyJ of course I know about JavaBeans, but their universality is [questionable](http://stackoverflow.com/questions/1568091/why-use-getters-and-setters). I believe using public fields will be perfectly fine in my case. – Ernest Sadykov Sep 10 '15 at 19:39
  • 1
    Can you elaborate on the reason for not adding getters/setters to your User class? Is it an existing API? If not and the reason is not to have the getters/setters pollute your class, my recommendation would be using lombok: https://projectlombok.org/ for generating accessors. We are using Lombok extensively with Spring and it can remove much of the code that is just there for convention, but reduces readability of your code. – revau.lt Oct 07 '15 at 07:02

1 Answers1

1

As mentionned in my comment if the reason for not wanting getter/setters is code clutter, I would recommend Lombok.

Here is a typical model class, that can be constructed by Spring (@NoArgsConstructor + @Data for getters and setters). @Builder and @AllArgsConstructor allow the generation of the Builder pattern with all fields.

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class SubscriptionData {

    @Id
    @Indexed
    private UUID key;

    private String productId;

    private String receiptString;

    private Date expirationDate;

}

Here is an example of a Spring service with constructor injection. The @RequiredArgsConstructor creates a constructor with all the non-initialized final fields and the onConstructor parameter adds the Spring-@Autowired annotation to it. If you have many service-dependencies this can remove quite some clutter.

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__({ @Autowired }))
public class OperatorServiceImpl implements OperatorService {

  private final WhoisService whoisService;

  ...
}
Ernest Sadykov
  • 831
  • 8
  • 28
revau.lt
  • 2,674
  • 2
  • 20
  • 31
  • You did not answer the question per se, but your answer is the most helpful one. Using Lombok I can avoid boilerplate code and use regular `BeanPropertyRowMapper`. – Ernest Sadykov Oct 07 '15 at 10:07