#DataJpaTest breaks after upgrade from Spring Boot 2.6.6 to 2.7.0 - spring

After upgrading to the latest Spring Boot Version, several tests in classes that have the annotation "#DataJpaTest" were no longer working. Many things broke, but what was specifically weird was that "findBy" methods do not seem to query data correctly (when I run integration tests or do manual tests, they work fine). Here is a basic test I ran:
#Test
fun `When findByActivationTokenId then return Account`() {
val firstName = "John"
val lastName = "Doe"
val phone = "1234"
val email = "test#gmail.com"
val providerId = "google"
val providerUserId = "123"
val activationToken = UUID.randomUUID()
val account = Account(
firstName = firstName,
lastName = lastName,
email = email,
phoneNumber = phone,
providerId = providerId,
providerUserId = providerUserId,
title = "Herr",
activationTokenId = activationToken
)
entityManager.persist(account)
entityManager.flush()
val allAccounts = accountRepository.findAll()
val found = accountRepository.findByActivationTokenId(activationToken)
found.get() shouldNotBe null
found.get().providerId shouldBe providerId
found.get().providerUserId shouldBe providerUserId
}
I called "findAll()" so I can look at the result with the debugger. What I noticed was that the repository does in fact return the account exactly the way I persisted it, with the right activation token ID. The "findByActivationTokenId", however, returns an empty optional. Is this a bug or an oversight on my part? I looked into the deprecation information and found nothing specific to Spring Data JPA that could effect tests only.

The problem is related to the embedded h2 database. With the latest upgrade, a lot of features will no longer work with JPA. Here is the changelog:
http://www.h2database.com/html/migration-to-v2.html
This is a more specific comment on the implications for migration to Spring Boot 2.7 and using the new Version:
https://twitter.com/odrotbohm/status/1526594686932160515

There are various things that might go wrong here, and just as mpbeaujean I suspect the new version of H2 to be the culprit.
There are various things you can try. Which one is the right one for you depends on your specific reason to use H2.
Don't use H2. Often H2 is used in tests while something else is used in production. This is a crutch at best and I recommend to switch to Testcontainers and a docker image of the exact database version you have in production.
You could revert to H2 1.4. Just note that there is a CVE for it. If I remember correctly you can mitigate it when you make sure that the JDBC URL used is trusted. But you should research the CVE in order to decide if it is a problem for you.
If you have to use the current version of H2, or if not using it doesn't resolve the problem, you need to find out what is going on.
I'd try the answers given here first.
If it doesn't help, please post the class definition of your entity, the DDL for your table and the SQL including parameters that gets executed.

Related

Why does Sonarqube mark try as a critical issue?

I'm currently facing an issue with some SonarQube's analysis being performed over some Kotlin code I wrote.
I'm trying to implement a method that connects to the database and returns accordingly to the query's result. I'm not sure how related this can be, but I added the following maven dependencies to my project:
Quarkus
Arrow
Ktorm
The code is the following:
#ApplicationScoped
class Repository(private val database: Database) {
override fun get(name: String): Either<Error, Brand> =
try {
database.brands.find { it.name eq name }.rightIfNotNull {
MissingBrandError("Missing brand")
}
} catch (e: Exception) {
Either.Left(DatabaseError(e.message))
}
}
class Error(val message: String)
class MissingUserError(val message: String) : Error(message)
class DatabaseError(val message: String? = null) : Error(message ?: "Some database error")
NOTE: Database object is of type org.ktorm.database.Database and brands is of type org.ktorm.entity.EntitySequence
The code is working and I also wrote unit tests for it that pass and give enough coverage (accordingly to the code coverage analysis tool), but at some point in my pipeline SonarQube marks the try as a critical issue with the following message:
Possible null pointer dereference in (...)Repository(String) due to return value of called method
I checked it online and I could find some related questions, but none of the provided answers worked for me. Amongst the many attempts these are the ones I can remember I tried without any success:
Not inlining any code (pretty much using Java style code)
Extracting the query result to a variable
Check with if/else statements for nullability instead (both with inlined try and without)
I'd also like to highlight that all I can see on Sonar is the generated report and CLI for the running build. I don't have access to any of its configuration or intended to change them (unless of course it comes down to that). The line I mentioned seems to be the only one affected by this problem according to Sonar's report, that's why this is the solo class I provided.
I hope I provided enough info and that any of you can help me with this. Thanks in advance.

FHIR.net Property added to Practitioner

We're currently using FHIR.net library(STU3). The FHIR Server from which we are receiving information has added a practitionerRole property to the Practitioner. Thus when Reading a Practitioner, we get the following Exception:
Encountered unknown member 'practitionerRole' while de-serializing (at path 'line 1, pos 2') in Hl7.Fhir.Rest.HttpToEntryExtensions.parseResource(String bodyText, String contentType, ParserSettings settings, Boolean throwOnFormatException)
The only solution I could think of is to add a practitionerRole property in the Model\Generated\Practitioner.cs class that would go like that:
[FhirElement("practitionerRole", InSummary = true, Order = 115)]
[Cardinality(Min = 0, Max = -1)]
[DataMember]
public List<Hl7.Fhir.Model.PractitionerRole> PractitionerRole
{
get { if (_PractitionerRole == null) _PractitionerRole = new List<Hl7.Fhir.Model.PractitionerRole>(); return _PractitionerRole; }
set { _PractitionerRole = value; OnPropertyChanged("PractitionerRole"); }
}
private List<Hl7.Fhir.Model.PractitionerRole> _PractitionerRole;
Is there any other solution than that? If so, which one?
Thank you in advance
It sounds like you're talking to a DSTU2 server. You'll need some sort of a conversion layer between your system and theirs.
As stated by FHIR employees in https://sea-region.github.com/standardhealth/shr_spec/issues/187 , DSTU2 and STU3 are two different versions of FHIR standard. If you check their last commits (https://www.nuget.org/packages?q=Fhir) as in August 2019, you will see they are maintaining both standards. That is probably due to the hospitals using STU3 version and do not want to adapt to the new version of FHIR, which is DSTU2.
The problem arises when you want to reach a class, let's say Patient, that coexists in two versions. Compiler can not decide which "Patient" class you refer to.
Normally, you could specialize using imports or predescription such as :
Hl7.Fhir.Model.Patient p = new Hl7.Fhir.Model.Patient();
BUT, Patient classes in both versions are described as Hl7.Fhir.Model.Patient. Their namespace is "Hl7.Fhir.Model" and their class name is "Patient".
Normally, you could workaround using keyword:
extern alias
BUT, since model classes in FHIR are read only, you can not use both versions in same project.
You need to uninstall unwanted FHIR version and install wanted version. To do these in Visual Studio,
go to Solution Manager> right click on "Manage Nuget Packages" > Search "Fhir" > uninstall unwanted FHIR version > install wanted version
You can also follow the unanswered question below:
C# T4 Template equivalent for "extern alias"

Spring Data MongoDB failed with "in" query

I'm using spring-data-mongodb 1.8.0; MongoDB 3.0.6; mongo-java-driver 3.1.0;spring-framework.version 4.0.3.
What I want is to query a list of user with certain phone numbers.
example for user: { "_id" : ObjectId("5625e5c32e1ca013a03f0d1b"), "phone" : "12345535"}
In Mongo Shell db.user.find({phone: { $in: [ "12345535", "123535"]}}) works fine. But in Spring I failed. Java Class User(with getters/setters omitted):
#Document(collection = "user")
public class User {
#Id
String id;
String phone;
}
What I tried is:
Query q = new Query(Criteria.where("phone").in("12345535","123535"));
mongoTemplate.find(q, User.class);
It comes to error:
Exception in thread "main" java.lang.IllegalAccessError: tried to access class org.springframework.beans.PropertyMatches from class org.springframework.data.mapping.PropertyReferenceException
at org.springframework.data.mapping.PropertyReferenceException.detectPotentialMatches(PropertyReferenceException.java:134)
at org.springframework.data.mapping.PropertyReferenceException.<init>(PropertyReferenceException.java:59)
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270)
at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.getPath(QueryMapper.java:837)
at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:729)
at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.with(QueryMapper.java:740)
at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.with(QueryMapper.java:686)
at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedKeyword(QueryMapper.java:258)
at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObjectForField(QueryMapper.java:200)
at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObject(QueryMapper.java:123)
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1700)
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1690)
at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:602)
at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:593)
at com.example.TestMongo.main(TestMongo.java:30)
But with changing field phone to id, same code works fine.
Query q = new Query(Criteria.where("id").in("5625e5c32e1ca013a03f0d1b","f0d1e"));
mongoTemplate.find(q, User.class);
With debugging, I find that it even didn't go to the request phase, error occurred in the query-building phase. It seems $in cannot be processed by PropertyPath.create, while in the id case, it can.
How can I fix this? I am a newbie and searched a lot but got no luck.Can you please help me out. Every answer is appreciated. Thanks guys.
As indicated in the announcement blog and the release train wiki, Spring Data MongoDB 1.8 requires Spring 4.1, ideally 4.1.8 which includes an important security fix.
The issue have appeared on me while using Spring 4.2.3.RELEASE and Spring MongoDB 1.6.1
Switching to Spring mongoDB 1.8.1 solves the issue.
(Meant as a comment to #OliverGierke's answer, but couldn't do it, due to low reputation level.)

Get "Invalid derived query" error all over the place in our Spring Data JpaRepository interfaces in STS 3.1

We have implemented our repositories exactly as demonstrated in the Spring Data documentation. Everything was fine until we upgraded from STS 2.9 to STS 3.1. All attempts to get these errors to disappear have failed, and in some cases they don't even make sense! They don't match any properties in either the interface or the entities used!
Here is an example:
public interface CreditNotesRepository extends JpaRepository<CreditNotes, Long> {
CreditNotes findCurrentCreditNotes(Long shipmentDetailId);
}
The findCurrentCreditNotes is a named query in our entity. This code executes perfectly fine.
#NamedQueries({
#NamedQuery(name = "CreditNotes.getCount", query = "SELECT COUNT(f) FROM CreditNotes f"),
#NamedQuery(name = "CreditNotes.findCurrentCreditNotes", query =
"SELECT creditNotes FROM CreditNotes creditNotes"
+ " WHERE creditNotes.shipmentDetail.shipmentDetailId = ?1 "
+ " AND creditNotes.notesSeqNumber = (SELECT max(creditNotes2.notesSeqNumber) FROM CreditNotes creditNotes2"
+ " WHERE creditNotes.shipmentDetail.shipmentDetailId = creditNotes2.shipmentDetail.shipmentDetailId)")
})
And the error we get:
Invalid derived query! No property find found for type ca.cole.freight.model.CreditNotes
Although this is just a flag (doesn't affect compilation), it is annoying and confusing. Can anyone shed some light on this? And explain it to me like I'm 6 years old! ;)
At the post on the Spring Forum, Spring Team announced that
It is already fixed for STS 3.3.0
I didn't check this version yet. But I'm using 3.5.0.RELEASE and the problem comes back! My fix is to uncheck Invalid Derived Query
It's an IDE error explained in the following post:
http://forum.springsource.org/showthread.php?138585-Invalid-derived-query!-No-property-delete-found-for-type-java-lang-Object
In the meantime, you can turn off the validation in preferences/spring/project validators/Data validator uncheck invalid derived query and STS wont throw the marker anymore.
There is also workaround for this. Add #Query annotation on your method definition in Your repository without JPQL/SQL query defined.
Here is example :
#Query
List<OwnerModel> findByFirstNameAndAgeNotZero(#Param(value = "firstName") String firstName);
In this case named query OrderModel.findByFirstNameAndAgeNotZero will be used. Your Eclipse error Invalid derived query should also disappear without need of disabling validation as described by #Tuan Dang
Checked on Eclipse 4.5.1 with Spring plugin installed for #NamedQuery and #NamedNativeQuery.
I've just been going through this myself. Unfortunately, the implementation of Spring Data changed between 1.1 and 1.2. It no longer supports the <repository> XML declaration. You can set up a custom postfix, but by default, it expects a bean of class name <InterfaceName>Impl. If it can't find the custom repository implementation, you start getting errors like the one you're encountering. It's trying to create methods to query for objects based on names of methods in your interface.
An alternative is to back your Spring Data version down to 1.1 and specify a schemalocation of http://www.springframework.org/schema/data/jpa/spring-jpa-1.1.xsd in your XML.

how to log work for a given issue using jira soap?

I'm working on a ruby on rails app which connects to Jira through jira soap. I browsed through the Jira SOAP API documentation but could not figure out a way to log time for an issue. What method(s) do I've to use to allow users to log time for some issue?
addWorklogAndAutoAdjustRemainingEstimate is the one I'm using in my scripts
This is a snippet of python code that might be useful to you:
d = datetime.datetime.now()
timestamp = "%s-%02d-%02dT%02d:%02d:00+01:00"%(d.year,d.month,d.day,d.hour,d.minute);
log = self.client.factory.create("ns0:RemoteWorklog")
log.comment = comment # a string
log.timeSpent = time # in the usual format (2h30m )
log.startDate = timestamp
# task is the name of the tast (a string)
self.client.service.addWorklogAndAutoAdjustRemainingEstimate(self.auth,task,log)
Via the addWorkLogXxx methods, where Xxx is what to do with the estimate.
for ruby developers,
worklog class from jira4r gem can be accessed via : Jira4R::V2::RemoteWorklog

Resources