Spring - Как вставить вложенный компонент с помощью класса SimpleJdbcDaoSupport - PullRequest
2 голосов
/ 22 мая 2010

У меня есть два компонента (POJO) - Клиент и класс адресов, определенный следующим образом:

public class Customer {
  private String name = null;
  private Address address = null;

  public Customer() {
    address = new Address();
  }

  public String getName() {
    return name;
  }

  public void setName(name) {
    this.name = name;
  }
  //additional setters/getters for various properties
}

public class Address {
  private String street = null;

  public String getStreet() {
    return street;
  }

  public void setStreet(street) {
    this.street = street;
  }
  //additional setters/getters for various properties
}

Я пытаюсь вставить это в базу данных, используя вот так:

public class CustomerDAO extends SimpleJdbcDaoSupport {
  public int addOrganization(Customer customer) {

    SimpleJdbcInsert insertCustomer = null;
    BeanPropertySqlParameterSource params = null;
    Number customerID = null;

    insertTransaction = new SimpleJdbcInsert(getDataSource()).withTableName("customers")
            .usingGeneratedKeyColumns("customerID");

    params = new BeanPropertySqlParameterSource(customer);

    customerID = insertTransaction.executeAndReturnKey(params);

    return customerID.intValue();
  }
}

Проблема в том, что я получаю Invalid argument value: java.io.NotSerializableException, и он не вставляет Клиента.Я могу удалить адрес из базы данных, и он будет вставлять другие данные клиента.Или я могу сделать что-то вроде этого:

MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("name", customer.getName());
params.addValue("street", customer.getAddress().getStreet());

, но это исключает простоту класса BeanPropertySqlParameterSource, и если я добавляю или удаляю какие-либо свойства, мне нужно добавить еще одну строку.

Есть ли простой способ сохранить вложенный адресный компонент без необходимости вручную добавлять каждое значение?Как мне определить базу данных и / или компоненты, чтобы это произошло?

Ответы [ 3 ]

1 голос
/ 24 мая 2010

Ваше решение самое простое.

Если вам необходимо вставить данные из вложенных объектов, и вы не хотите добавлять параметры на карту, тогда вам следует вместо этого использовать JPA.

1 голос
/ 25 июня 2013

Есть способ сделать это с помощью MapSqlParameterSource и отражения. Некоторый код ниже. (недостаток в том, что вам нужно использовать отражение, но преимущество в том, что вам не нужно беспокоиться о добавлении / удалении полей).

Вам потребуется, чтобы класс Customer и класс Address расширялись от AbstractBean или какого-либо другого класса.

public static MapSqlParameterSource generate(Customer bean) {
    try {
        MapSqlParameterSource source = new MapSqlParameterSource();
        addAllFields(bean, source, bean.getClass().getDeclaredFields());
        return source;
    } catch (IllegalAccessException e) {
        throw new IllegalStateException("Unable to generate the parameter source", e);
    }
}

private static void addAllFields(AbstractBean bean, MapSqlParameterSource source, Field[] fields)
    throws IllegalAccessException {
    for (Field field : fields) {
        field.setAccessible(true);
        if (field.getType().isAssignableFrom(Address.class)) {
            Address address = (Address)field.get(bean);
            addAllFields(address, source, address.getClass().getDeclaredFields());
        } else {
            source.addValue(field.getName(), field.get(bean));
        }
    }
}
0 голосов
/ 22 мая 2010

вы можете определить внутренние бобы. Взгляните на раздел 3.3.2.3 по внутренним компонентам. Это ссылка http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-inner-beans

...