Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not Able to access Id (auto generated field) post save operation #149

Closed
bhishambajaj1999 opened this issue Sep 27, 2023 · 3 comments
Closed
Assignees

Comments

@bhishambajaj1999
Copy link

return ordersRepository.save(orders)
.flatMap(savedOrder -> {
// Access the saved entity with the populated id
Long orderId = savedOrder.getId();
log.info("OrderId.....{}", orderId); // Getting null here..

      // Perform operations on the id if needed
      // ...

      return Mono.just("Insert Successful"); // Return a success message
    })
    .doOnSuccess(successMessage -> log.info("Successfully Inserted"))
    .doOnError(error -> log.error("Failed to Insert", error));

}

@id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@column(name = "id", nullable = false)
private Long id;

mysql: id bigint NOT NULL AUTO_INCREMENT,
The field is getting persisted correctly in database, but I am not able to access it.

@jchrys
Copy link
Collaborator

jchrys commented Sep 30, 2023

Hello, @bhishambajaj1999.
Unfortunately, I'm unable to replicate this problem in my current environment.
Would it be possible for you to provide us with a reproducer?

@jchrys jchrys self-assigned this Sep 30, 2023
@jchrys jchrys added the need-more-info requested for more information label Sep 30, 2023
@bhishambajaj1999
Copy link
Author

Hello, @jchrys , Please find additional info.
public class Orders {

@id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@column(name = "id", nullable = false)
private Long id;

@column(name = "order_id", nullable = false)
private String orderId;

@column(name = "status", nullable = false)
@Enumerated(EnumType.STRING)
private OrderState status;

@column(name = "type", nullable = false)
@Enumerated(EnumType.STRING)
private OrderType type;

@column(name = "client_code", nullable = false)
private String clientCode;

@column(name = "billing_code", nullable = false)
private String billingCode;

@column(name = "pincode", nullable = false)
private String pincode;

@column(name = "address", columnDefinition = "json", nullable = false)
@type(type = "json")
private Address address;

@column(name = "lab_id")
private Long labId;

@column(name = "tenant_id", nullable = false)
private String tenantId;

@column(name = "contact_no", nullable = false)
private String contactNo;

@column(name = "contact_no_hashed", nullable = false)
private String contactNoHashed;

@column(name = "email_id")
private String emailId;

@column(name = "origin", columnDefinition = "json", nullable = false)
@type(type = "json")
private Origin origin;

@column(name = "referred_by", nullable = false)
private String referredBy;

@column(name = "is_deleted", columnDefinition = "bit(1)", nullable = false)
private boolean isDeleted;

@column(name = "attributes", columnDefinition = "json", nullable = false)
@type(type = "json")
private OrderAttributes attributes;
}

This is my R2dbcConfig
@bean
public ReactiveTransactionManager transactionManager(ConnectionFactory connectionFactory) {
return new R2dbcTransactionManager(connectionFactory);
}

@OverRide
@bean
@primary
public ConnectionFactory connectionFactory() {
ConnectionFactoryOptions baseOptions = ConnectionFactoryOptions.parse(r2dbcProperties.getUrl());
ConnectionFactoryOptions ob = ConnectionFactoryOptions.builder().from(baseOptions)
.option(USER, r2dbcProperties.getUsername())
.option(PASSWORD, r2dbcProperties.getPassword())
.build();

ConnectionFactory connectionFactory = ConnectionFactories.get(ob);
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
ConnectionPoolConfiguration.Builder builder = ConnectionPoolConfiguration.builder(
    connectionFactory);
R2dbcProperties.Pool pool = r2dbcProperties.getPool();
map.from(pool.getMaxIdleTime()).to(builder::maxIdleTime);
map.from(pool.getMaxLifeTime()).to(builder::maxLifeTime);
map.from(pool.getMaxAcquireTime()).to(builder::maxAcquireTime);
map.from(pool.getMaxCreateConnectionTime()).to(builder::maxCreateConnectionTime);
map.from(pool.getInitialSize()).to(builder::initialSize);
map.from(pool.getMaxSize()).to(builder::maxSize);
map.from(pool.getValidationQuery()).whenHasText().to(builder::validationQuery);
map.from(pool.getValidationDepth()).to(builder::validationDepth);

return new ConnectionPool(builder.build());

}

@bean
ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {
ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
initializer.setConnectionFactory(connectionFactory);
return initializer;
}

@OverRide
@bean
public R2dbcCustomConversions r2dbcCustomConversions() {
List<Converter> converters = new ArrayList<>();
converters.add(new OrdersReadingConverter(objectMapper));
converters.add(new OrdersWritingConverter(objectMapper));

return new R2dbcCustomConversions(getStoreConversions(), converters);

}

Sharing Reading convertor
public Orders convert(Row source) {

return Orders.builder()
    .id(source.get("id",Long.class))
    .orderId(source.get("order_id", String.class))
    .status(OrderState.valueOf(source.get("status", String.class)))
    .type(OrderType.valueOf(source.get("type", String.class)))
    .clientCode(source.get("client_code", String.class))
    .billingCode(source.get("billing_code", String.class))
    .pincode(source.get("pincode", String.class))
    .address(objectMapper.readValue(source.get("address", String.class), Address.class))
    .labId(source.get("lab_id", Long.class))
    .tenantId(source.get("tenant_id", String.class))
    .contactNo(source.get("contact_no", String.class))
    .contactNoHashed(source.get("contact_no_hashed", String.class))
    .emailId(source.get("email_id", String.class))
    .origin(objectMapper.readValue(source.get("origin", String.class), Origin.class))
    .referredBy(source.get("referred_by", String.class))
    .isDeleted(Boolean.TRUE.equals(source.get("is_deleted", Boolean.class)))
    .attributes(
        objectMapper.readValue(source.get("attributes", String.class), OrderAttributes.class))
    .build();

}

The requirement is to do operation on auto generated id, which I am not able to retrieve, but It is getting saved in database correctly. Currently I am handling this by explicitly calling
return databaseClient.sql("SELECT LAST_INSERT_ID()")
.map((row, metadata) -> row.get(0, Long.class))
.one();

    In Jpa I am able to retrieve this auto generated Id implicitly, I am new to R2dbc not sure if it is supported implicitly, if yes not sure what is going wrong here.
    
    I am using spring boot **2.7.4**
   implementation("io.asyncer:r2dbc-mysql:0.9.4") => Driver for r2dbc

@jchrys
Copy link
Collaborator

jchrys commented Sep 30, 2023

Hello, @bhishambajaj1999.
Thank you for providing the information. It appears that the details you've shared are not quite sufficient for me to replicate the issue in my own environment(https://stackoverflow.com/help/minimal-reproducible-example). However, it seems that the issue may be related to either spring-data-r2dbc or spring-data-relational. I would suggest considering reaching out to the respective project team.

@jchrys jchrys added external-project and removed need-more-info requested for more information labels Sep 30, 2023
@jchrys jchrys closed this as completed Oct 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants