使用 JOOQ 从 POJO 设置字段为 null
Set fields null from POJO using JOOQ
根据来自 JOOQ 博客的 this entry,标题为 "SQL DEFAULT expressions and POJOs" 的部分表示来自 POJO 的任何空字段都会将列设置为空,因为每个 Record.changed()
标志都将是设置为真。
在实践中,我没有发现这种情况——如果 POJO 字段为空并且我遵循博客中的示例,则保留现有值。我想将这些字段设置为空,但我如何使用 POJO 来实现?
// Load the customer record from a POJO
CustomerRecord customer = ctx.newRecord(CUSTOMER, customerPojo);
customer.update();
// Expected behavior: null fields in customerPojo will set db values to null
// Actual behavior: null fields in customerPojo do not change values in db
编辑:这是使用 Jooq 3.11.10,Postgres 10.6。
创建客户脚本:
drop table if exists customers;
create table customers
(
id serial not null primary key,
first_name text,
last_name text
);
客户Class:
@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
private Integer id;
private String firstName;
private String lastName;
public static Customers TAB = Customers.CUSTOMERS;
static DSLContext ctx = PostgresSingleton.getMainCtx();
public Customer store(){
CustomersRecord rec = ctx.newRecord(TAB, this);
if(getId() == null) {
rec.store();
}
else {
rec.update();
}
rec.refresh();
return rec.into(Customer.class);
}
}
测试(Spock/Groovy):
def "Customer test"() {
when: "save a new customer"
Customer cust = Customer.builder().firstName("Phil").lastName("H").build().store()
then: "ID populated"
def custId = cust.getId()
custId != null
when: "null out last name"
cust.toBuilder().lastName(null).build().store()
then: "last name actually set to null"
cust.getId() == custId
cust.getFirstName() == "Phil"
cust.getLastName() == null //fails, still is "H"
}
编辑 2:
看来 .update()
调用实际上是在清空数据库中的字段!但是,之后的 .into()
调用不会按预期刷新具有空字段的 POJO。我在 .refresh()
之后验证了 lastName 的 value
为空,但 into()
调用并未使该值为空。
好吧,这是一个 PEBKAC 错误——我没有将更新结果存储回测试中的同一个对象:
when: "null out last name"
cust.toBuilder().lastName(null).build().store() //not storing the result!
应该是:
when: "null out last name"
cust = cust.toBuilder().lastName(null).build().store()
容易错过。
根据来自 JOOQ 博客的 this entry,标题为 "SQL DEFAULT expressions and POJOs" 的部分表示来自 POJO 的任何空字段都会将列设置为空,因为每个 Record.changed()
标志都将是设置为真。
在实践中,我没有发现这种情况——如果 POJO 字段为空并且我遵循博客中的示例,则保留现有值。我想将这些字段设置为空,但我如何使用 POJO 来实现?
// Load the customer record from a POJO
CustomerRecord customer = ctx.newRecord(CUSTOMER, customerPojo);
customer.update();
// Expected behavior: null fields in customerPojo will set db values to null
// Actual behavior: null fields in customerPojo do not change values in db
编辑:这是使用 Jooq 3.11.10,Postgres 10.6。
创建客户脚本:
drop table if exists customers;
create table customers
(
id serial not null primary key,
first_name text,
last_name text
);
客户Class:
@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
private Integer id;
private String firstName;
private String lastName;
public static Customers TAB = Customers.CUSTOMERS;
static DSLContext ctx = PostgresSingleton.getMainCtx();
public Customer store(){
CustomersRecord rec = ctx.newRecord(TAB, this);
if(getId() == null) {
rec.store();
}
else {
rec.update();
}
rec.refresh();
return rec.into(Customer.class);
}
}
测试(Spock/Groovy):
def "Customer test"() {
when: "save a new customer"
Customer cust = Customer.builder().firstName("Phil").lastName("H").build().store()
then: "ID populated"
def custId = cust.getId()
custId != null
when: "null out last name"
cust.toBuilder().lastName(null).build().store()
then: "last name actually set to null"
cust.getId() == custId
cust.getFirstName() == "Phil"
cust.getLastName() == null //fails, still is "H"
}
编辑 2:
看来 .update()
调用实际上是在清空数据库中的字段!但是,之后的 .into()
调用不会按预期刷新具有空字段的 POJO。我在 .refresh()
之后验证了 lastName 的 value
为空,但 into()
调用并未使该值为空。
好吧,这是一个 PEBKAC 错误——我没有将更新结果存储回测试中的同一个对象:
when: "null out last name"
cust.toBuilder().lastName(null).build().store() //not storing the result!
应该是:
when: "null out last name"
cust = cust.toBuilder().lastName(null).build().store()
容易错过。