constructor #Builder de loombok en JPA query - jpa

Quiero hacer una consulta con Spring boot usuando la anotacion #Builder de loombok, para crear constructores personalizados en la consulta.
#Query("select com.multiplos.cuentas.pojo.solicitud.SolicitudResponse.builder().identificacion(s.inversionista.persona.identificacion).build()")

Constructor queries are a JPA thing, and will execute a constructor method for you. Lombok on the other hand requires multiple method calls, and isn't want JPA constructor methods are meant for. You are much better off giving a constructor method to the query to use; you will not gain anything I can see from forcing Lombok where it doesn't fit.
Alternatively, return the raw "s.inversionista.persona.identificacion" data and do it yourself in a stream on the output.

Related

Spring data inject repository without explicit type

I have a service that needs to use Neo4jRepository (regular repository provider by spring data).
public class SomeServiceBean<T>{
#Autowired
private Neo4jRepository<T,Long> Neo4jRepository;
}
This class will generate en error:
expected single matching bean but found 2: systemUserRepository,systemClaimRepository
The problem is that systemClaimRepository and systemUserRepository is extending Neo4jRepository<T,Long> as a bean without implementation.
Spring see systemClaimRepository and systemUserRepository as Neo4jRepository<T,Long> because they are extending it.
Is there anyway to inject Neo4jRepository<T,Long>?
Thanks
No how should this work?
You have two beans that match the interface and Spring does not know which implementation to inject.

Way to enforce length check constraint in MyBatis

I have some check constraints defined by SYS schema in DB for a particular column.
Now, while invoking it from Java code through MyBatis, is there anyway to enforce corresponding field length validations through MYBatis configuration only.
PS: I don't want to enforce constraints at VO level (setter individually). Or using JSR 303
DataBase : Oracle 11g
Using MyBatis
If you do not want to validate in your java beans (manually, or using JSR 303) I think you could write your own typeHandler for those field.
Typehandler would handle String fields and do validation.
See code example for String TypeHandler.
You could enforce your validation logic (of any complexity) in handler's get/set methods.
If you want to use TypeHandler to trim string to given length when saving to database, do it in setNonNullParameter method.
Sample code below
#MappedJdbcTypes(JdbcType.VARCHAR)
public class ExampleTypeHandler extends BaseTypeHandler<String> {
#Override
public void setNonNullParameter(PreparedStatement ps, int i,
String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter.substring(0,DESIRED_MAX_LENGTH));
}
You could also trim (or otherwise modify) values you read from database- you need to modify get* method in your TypeHandler implementation to do that.
You must tell mappers to use your handler. Otherwise, default handler for given type will be used.
Your SQLs in XML file must use syntax
#{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
Check https://mybatis.github.io/mybatis-3/sqlmap-xml.html for details.

Does intellij idea offer auto completion for non getter el methods?

I have auto completion out of the box for getter methods in jsp expression languages with intellij. I don't have it however for non getter methods (part of EL 2.2, which is maintained as part of Servlet 3.0 / JSP 2.2).
Idea does however recognise the call to non getter methods in El as valid.
Is there any way to turn auto completion on for the non getter method ?
Thanks,
Alain
It seems that IDEA-115227 is the issue to add your comments and votes to.

Does Dependency Injection go against OOP?

I feel like using Dependency Injection is changing the way I write my object oriented code. For instance, below is what I would do without DI
Interface: DataAdapter
SqliteDataAdapter implements DataAdapter
XMLDataAdapter implements DataAdapter
OracleDataAdapter implements DataAdapter
// Initialization
DataAdapter adapter = new SqliteDataAdapter();
DataAdapter adapter = new XMLDataAdapter();
DataAdapter adapter = new OracleDataAdapter();
but using DI my code structure would be:
Interface: DataAdapter
SqliteDataAdapter implements ISqliteDataAdapter, DataAdapter
XMLDataAdapter implements IXMLDataAdapter, DataAdapter
OracleDataAdapter implements IOracleDataAdapter, DataAdapter
// Initialization
ISqliteDataAdapter adapter = new SqliteDataAdapter();
IXMLDataAdapter adapter = new XMLDataAdapter();
IOracleDataAdapter adapter = new OracleDataAdapter();
The reason for this change is that in my module I can bind 1 interface to 1 class.
Is this a bad practice? If yes what is the correct solution?
Doesn't DI change the whole purpose of using interfaces?
EDIT:
The following is my binding for DI container
bind(ISqliteDataAdapter.class).to(SqliteDataAdapter.class);
bind(IXMLDataAdapter.class).to(XMLDataAdapter.class);
bind(IOracleDataAdapter.class).to(OracleDataAdapter.class);
If i do as suggested, how would I be able to use multiple adapters? What if I need to use both XMLDataAdapter and SQLDataAdapter in my application?
bind(DataAdapter.class).to(SqliteDataAdapter.class);
Edit:
Here is the current call to get an instance:
#inject protected ISqliteDataAdapter dataAdapter;
Here is how I should do it with having 1 interface only:
#inject protected DataAdapter dataAdapter;
// In this case I don't have a choice on which type of data adapter It's going to create
// It's already defined in my module file and it's pointing to one of the 3 DataAdapters
So what I'm trying to understand is, how can I structure my code in a way that I have control over the type of object it's injecting, without having interface for every type of DataAdapter.
I would say that DI is a natural consequence of having interfaces. The reason we have interfaces is so that we can write code that doesn't depend on particular class, but instead an work with a multitude of classes without any changes. Even if we expect there to only be one class which does we need, this may change in the future. By programming to interface, we can even account for changes we can't imagine.
DI just uses the above notions in a peculiar way, to maximize the testability and adaptability of code. So I would say the DI is a really good practice.
That said, I think there is one warning to be issued for anyone involved with these kinds of systems. There's the danger that we write full-fledged classes like your SqliteDataAdaptor, and then push a "extract the interface" button to give the ISqliteDataAdaptor interface. This practice is very bad, particularly if it happens a lot. Instead, ISqliteDataAdaptor should usually be designed first, and then a sensible implementation can be written.
Dependency injection is about controlling what is instantiated and placing that logic in a single place. The code you write should not change the base types(interfaces) that you use.
In both cases you should have DataAdapter as the type of object you use. It's you who decides what the type of the instance that you get from the dependency injection container not the container.
also see this

JPA from EclipseLink to which provider?

Hallo all.
I'm using EclipseLink as JPA provider in our project. As described here
we have e big problem with char trimming with a DB char column with EclipseLink
I tried the way to remove the jdbc bind parameter but I cannot make this change for production environment: I tried to write my own SessionCustomizer but it doesn't seem to work.
public class ContrattoSessionCustomizer implements SessionCustomizer {
/**
* #see org.eclipse.persistence.config.SessionCustomizer#customize(org.eclipse.persistence.sessions.Session)
*/
#Override
public void customize(Session session) throws Exception {
System.out.println("hello.....");
DatabaseLogin login = (DatabaseLogin)session.getDatasourceLogin();
login.setShouldTrimStrings(false);
}
}
I would like to migrate from EclipseLink to another JPA provider; yesterday I tried with hibernate but unfortunately to migrate to this provider I need to change my domain model, since it seems that hibernate does not support some mapping definition that I used with eclipse link.
Is there another good provider to test without make changes to my domain model mapping?
Kind regards
Massimo
Can't see how changing providers will help you, as it is a database issue.
You seemed to state that you solved the issue by disabling parameter binding?
Are you registering your SessionCustomizer in your persistence.xml?