Amazon Q: What did I learn today ?
Let’s face it clearly: we, software developers and programmers, don’t like to read here and there that AI generated code is any worth. That’s understandable: after having spent years to learn programming languages, algorithms, operating systems, deployment and configuration tools, building platforms and more others, after having written robust and reliable code for dozens of major projects, it’s difficult to accept that an important part, to say the least, of our added value and expertise, be automatically generated by dumb stochastic parrots.
Fortunately, things aren’t as described here and the ML (Machine Learning) powered assistants, freely distributed and integrated with most IDEs, aren’t about to replace us, far from it. However, this idea according to which more or less anyone would be able to generate, in a couple of clicks, complex production-ready software applications, based on a simple plain text description input, is gaining more and more ground, especially within the ranks of some CEOs/CIOs, who see here an “opportunity” to allegedly reduce expanses by laying off hundreds of persons. Hence, a certain hostility and mistrust that we, software developers and programmers, have when it comes to discuss generative AI tools dedicated to write code.
It was as well my case until recently. But then I tried Amazon Q, integrated with IDEs like Intellij IDEA, Visual Studio Code and others. And to my great surprise, it’s really useful ! Okay, to be absolutely clear, the autocomplete functions and the suggested code snippets are very practical, but not more. Especially that users didn’t need to wait for NLP (Natural Language Processing) and DL (Deep Learning) powered tools in order to have them. But talking about the code generation itself, it’s not that bad ! Of course, it still requires a lot of work before becoming professional, production-ready code, but the idea is there and the skeleton is decent.
So, I’m using this kind of coding assistant since a couple of months now and I think that it saves me about 10 - 20% of the time that I used to spend searching for ideas, solutions and other stuff. Nothing spectacular here, this was expected as technology doesn’t ever stop to raise the bar, right ? But I guess that where I was quite bowled over is that, today, I even learned something from Amazon Q. Let me explain.
Java enterprise grade applications and microservices expose REST APIs which accept DTOs (Data Transfer Objects) as input and output arguments. These DTOs are the little cousins of the entities, dedicated instances used for persistence purposes. And one of the common operations that any enterprise grade application uses to allocate a lot of its processing time is the mapping between the DTOs and the entities and reversely.
Some class libraries exist to allegedly facilitate this process and one of the most known is MapStruct, very familiar to the Java developers. I’m not myself a fan of these kind of class libraries as I think that there doesn’t exist a simpler operation then this mapping and, hence, it doesn’t require any library, but I know that some developers adore them. Anyway, Amazon Q taught me today that MapStruct can be integrated with the JPA (Java Persistence API) layer, such that to come to a mapping code that some developers might like. Let’s see an example.
Consider the following Java DTO:
public record OrderDTO(Long id, String item, BigDecimal price, Long customerId) {..}
and its associated entity:
@Entity
@Table(name = "ORDERS")
public class Order
{
@Id
@GeneratedValue
private Long id;
@Column(name = "ITEM", nullable = false, length = 40)
private String item;
@Column(name = "PRICE", nullable = false)
private BigDecimal price;
@ManyToOne
private Customer customer;
...
}
As you can see, the entity Order
is in a Many-to-One
relationship with another
entity named Customer
. It is the many part of the relationship and, as such, it
contains the associated Customer instance. This is very usual.
The OrderDTO
instance, on the other hand, doesn’t contain the associated instance
of the CustomerDTO
, but only its ID. This is also usual for DTOs which are light
business object versions and, consequently, not supposed to have any persistence
related information.
Given such a scenario, the DTO to entity mapping process needs to use the
Customer
ID and to search the datastore for the associated entity. And despite
that this operation is a trivial one when implemented explicitly, some developers
prefer to describe it, in a more hermetic mode, as follows, using MapStruct:
@Mapper(componentModel = "cdi", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface OrderMapper
{
OrderMapper INSTANCE = Mappers.getMapper(OrderMapper.class);
@Mapping(source = "customer.id", target = "customerId")
OrderDTO fromEntity(Order order);
@Mapping(source = "customerId", target = "customer", qualifiedByName = "findCustomerById")
Order toEntity(OrderDTO dto, @Context CustomerService customerService);
@Named("findCustomerById")
default Customer findCustomerById(Long customerId, @Context CustomerService customerService)
{
return customerService.findCustomerById(customerId);
}
}
As you can see, the toEntity(...)
method, which maps the DTO to the associated
entity, takes an attribute named qualifiedName
, that represents a helper used
to perform the mapping of an ID to the entity identified by it. This helper is
further defined using the org.mapstruct.Named
annotation and uses the service
layer (CustomerService
) in order to find the entity corresponding to the given
ID. This way, we map the customer ID in the CustomerDTO
instance to the
corresponding customer entity.
While there are dozens of other simpler ways to implement this functionality, I know for sure, from my experience, that a lot of developers prefer that one. My point isn’t to recommend it but simply to say that I completely ignored that MapStruct had this integration feature. Which isn’t a surprise per se as I’ve always used MapStruct very seldom and at maximum 30% of what’s able to do.
No, my point was simply to say that, no matter how experienced you might be, you have always something new to learn. And you can learn from anyone or anywhere, including Amazon Q, GitHub Copilot and other Code Whisperers !