Injecting spring dependencies into Domain objects best practices? - spring

I've scraped all over many resources, and have made this work and it's kinda complex, which turns me into asking for review and other ideas on how to properly inject spring dependencies into DomainObjects ..
My solution so far includes ..
Defining the dependencies needed for loadweaving
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
And then .. configure it in the spring context file :
<context:spring-configured />
<context:load-time-weaver/>
Using #Configurable for my domain classes :
#Configurable
public class MyDomainClass {
....
}
And of course, using these VM arguments :
-XX:-UseSplitVerifier -javaagent:C:/Users/albert/.m2/repository/org/springframework/spring-instrument/3.0.6.RELEASE/spring-instrument-3.0.6.RELEASE.jar
For this current solution, i have the feeling that this seems too much, like the lots of dependencies needed, and also the VM args, which i would dislike when deploying in production server where i have to use specific options, which i fear could be not supported in the future or perhaps have different behaviours between version.
Im thinking of doing domainObjects with prototype scope, but i fear the dependencies issues when fetching the domain objects from the database (not from applicationContext).
Please share your experiences, thank you !

1: When you start injection stuff dynamically into domain objects, they're really not domain objects any more in the sense that the domain should reflect your information model, independent of any business rules and functional logic.
2: Remember KISS (keep it simple...). At some point, someone else might have to take ownership and maintain your code so have some mercy on that person :)
I would call this an anti-pattern, which in my opinion should be avoided.

If you use compile time waving, then you will not need the VM argument.

Related

Maven property overriding conflict between parent/bom

I am currently facing an issue with my maven configuration. I was thinking it will work in a way where versions in MyBom will have higher priority on the grand-grand-parent defined versions.
This is the setup :
enter image description here
In spring-dependencies, I have this version <atomikos.version>4.0.6</atomikos.version>.
In myBom, I have this version <atomikos.version>5.0.106</atomikos.version>.
Both spring-dependencies and MyBom have the
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jta</artifactId>
<version>${atomikos.version}</version>
</dependency>
I have imported the bom as usual in "MyParent":
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>myBom</artifactId>
<version>${myBom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Finally, in "MyProject", when I am showing the effective pom, it uses the version 4.0.6 coming from the spring-dependencies.
I was expecting the version to be 5.0.106 as the bom redefine it in a sublayer.
Note that it can work with any dependency which is common between bom and parent.
So, currently, my only viable solution is to manually set the the version in "MyParent" which is making the creation of "MyBom" useless...
Can you confirm what is correct ? My assumption (meaning I have a misconfiguration somewhere) or the current behavior, meaning "MyBom" is worthless.
As far as I know, "direct" entries in the dependencyManagement always take precedent over BOMs, not matter what the inheritance level is.
You should probably just override the <atomikos.version> property.
This is not possible to override parents version from "MyBom" project. The only solution is to remove the spring-boot-starter-parent as parent and import the spring-dependencies at same level of "MyBom" import.
I found the solution but I would like to thank #J Fabian Meyer to also point the correct solution.
The dependencyManagement is just a declaration of what the version of the dependency should be when really used as a project dependency. Thus you still should declare (use) the myBom dependency. Also, the scope "import" is invalid.
See the documentation
https://maven.apache.org/pom.html#dependency-management
https://maven.apache.org/pom.html#Dependencies

WebClient create java.lang.ExceptionInInitializerError: null ExchangeStrategies.withDefaults

I'm trying to play around Spring WebFlux Webclient.
Tried to create a simple webclient in a quartz cron job
this.webClient = WebClient.create(this.queryUrl);
I made sure the queryUrl is valid.
However, I've got an error as following:
java.lang.ExceptionInInitializerError: null
at org.springframework.web.reactive.function.client.ExchangeStrategies.withDefaults(ExchangeStrategies.java:67)
at org.springframework.web.reactive.function.client.DefaultWebClientBuilder.initExchangeStrategies(DefaultWebClientBuilder.java:302)
at org.springframework.web.reactive.function.client.DefaultWebClientBuilder.build(DefaultWebClientBuilder.java:269)
at org.springframework.web.reactive.function.client.WebClient.create(WebClient.java:154)
Tracing into the code, I've found that
DefaultExchangeStrategiesBuilder is null.
Does anyone have any idea what is missing?
It's a simple web client.
Thanks.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.0</version>
</dependency>
Adding these dependencies and making sure the versions are the same.
I only had jackson-core before.
I tried to move the job out of quartz and ran it directly in main.
it still threw an exception, but it's different and I then looked it up
and some one has asked the issue and the solution to make sure both jackson packages need to be included and versions must be same.
I then added them to the pom file. try to run the job and it worked.
Putting the job back to quartz to run and it also worked.

Scheduling using Camel - Quartz2 and Spring boot

I am trying to setup a scheduler using Camel and Quartz2 and my goal is to read messages from queue only in a specific time period.I am getting the following error on start of the server.
org.apache.camel.spring.boot.CamelSpringBootInitializationException:
org.apache.camel.FailedToCreateRouteException: Failed to create route
route1:
Route(route1)[[From[quartz2://simpleTimer?cron=0/1+0+13-15+?...
because of Failed to resolve endpoint:
quartz2://simpleTimer?cron=0%2F1+0+13-15+%3F+*+MON-FRI due to: No
component found with scheme: quartz2
This is the pom entry
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-quartz2</artifactId>
<version>2.19.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-dependencies</artifactId>
<version>2.19.2</version>
</dependency>
code snippet in routes
from("quartz2://simpleTimer?cron=0/1+0+13-14+?+*+MON-FRI")
.log("Reading msgs")
.from("some queue")
.bean("myBean")
Also tried with this
from("quartz2://testGroup/someName?cron=0/1+0+13-14+?+*+MON-FRI").
I made multiple attempts in fixing the issue but failed, can anyone help me in fixing this?
Can I use simpleTimer along with Cron settings or Is there any other approach?
any suggestions/help in this regards would be highly appreciated.
The error indicates you have not added the dependency in maven to camel-quartz2 component.
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-quartz2</artifactId>
<version>x.x.x</version>
<!-- use the same version as your Camel core version -->
</dependency>
The problem is that you put 2 from in the same route. Each route has only one from.
When you read from a queue, for example with jms component, you get directly the messages as soon as they arrive. So quarz component is not needed.
Which component are you using for reading from a queue? Probably this component has more options that they can help you!
This got resolved when I created a Bean instance of QuartzComponent in routes file.Also, we can have multiple "from" in the routes definition.

Spring Data Projection not working

I want to use spring projection in my project. I am doing exactly as mentioned at this url http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
interface NoAddresses {
String getFirstName();
String getLastName();
}
The only difference is my interface is public. and is not in the same package as the repository. Is that a requirement?
Still I see the whole entities are being returned, instead of just the projected columns.
I have
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.2.RELEASE</version>
</dependency>
Doesn't work. Do i need to add some dependency to make the projection work? I am not using spring-boot but just the spring-data stuff in my project, running on tomcat server.
thanks
Chahat

Can't delete Node with Cypher

i am working on Spring Data Neo4j and use Cypher-Language for some Queries. Works fine so long, but delete a Node don't work.
For Example:
#Query("start u=node(5) delete u")
void deleteNode();
i use the dependencies
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-cypher</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-kernel</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j-rest</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
i cannot use version 1.7.2 of Cypher because it conflict with spring data neo4j and the kernel 1.6.
Can anybody help me?
i don't want to delete a Node with
repository.delete(5);
Because i also want to delete Relationships and any more.
Thx!
I think you should delete the relationship with the node you want to delete.
#Query("start u=node(5) delete u")
If you want to delete a node ,you should confirm the node haven't relationship with other node.
Please have a try with following codes:
#Query("start u=node(5) match u-[r]-() delete u,r")
Interesting idea, didn't try that yet b/c SDN still officially points to Neo4j 1.7 but that will change soon.
Why can't you update to SDN 2.1.RC2 ?
SDN 2.0.1 doesn't work with Neo4j 1.8 as there were API changes in Neo4j.
You will need to add #Transactional to the method as well.

Resources