Not able to write junit test case for jpa specification - jpa

I have a PersonServiceImpl class in which I am fetching record from repository like this.
personRepo.findAll(**new Specification<Person>**() {
#Override
public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, Criteria Builder cb) {
}
}, pageable);
I am trying to cover this whole predicate method using JUnit but not able to do this. It's only covering all codes except inner part of find All.
I have spent much time over internet but didn't find any solution. Please help.

Related

MongoDB Compass Export Pipeline to Language with other style

In MongoDB Compass, when I choose to export the Aggregation Pipeline to Java, I get something like this:
Arrays.asList(new Document("$group",
new Document("_id", "$loginTime.seconds")
.append("loginTime",
new Document("$min", "$loginTime.seconds"))))
While this seems to be correct, I'd like to know how I can generate the equivalent expression:
List.of(Aggregates.group("$loginTime.seconds", Accumulators.min("loginTime", "$loginTime.seconds)));
Obviously the latter is more straight-forward and declarative enough to understand on first sight. But MongoDB Compass does not offer any option for that. Why.
I researched a bit based on the comment from #prasad_
It seems that there are related issues on the mongoDB issue tracker
see https://jira.mongodb.org/browse/COMPASS-4695
I also think that this would be a very nice feature since longer aggregations are just unreadable and if we need to adapt these we have to re-engineer them quite often.
Have you thought about saving your aggregation stage as a view in the database? Then the pipelines are stored in the mongodb and you can query it like any other collection.
Other than that I thought about exporting the pipeline as js / json / or raw pipeline (I prefer js/json for auto-formatting) and then parse it from a resource folder.
Of course this would mean that you have to somehow come up with a mechanism to replace dynamic parts of the query which could lead to security issues probably, but maybe you can break down parts that are not dynamic.
Aggregation aggregation =
newAggregation(
CustomDocumentAggregationOperation.of(
matchByIdAndOtherValues(objectId, otherValues),
lookupSomeDataOfOtherCollection(),
unwindSomething(),
projectToSomething()));
I adapted this pattern within my repositories so that I can see at a first glance what the aggregation is doing. Hidden behind these static functions is a bunch of bson.Documents and I try to avoid going there...
This is how I assemble multiple Documents to one AggregationOperation
public class CustomDocumentAggregationOperation implements AggregationOperation {
private final Document document;
public CustomDocumentAggregationOperation(Document document) {
this.document = document;
}
#Override
public Document toDocument(AggregationOperationContext aggregationOperationContext) {
return aggregationOperationContext.getMappedObject(document);
}
public static AggregationOperation of(Document document) {
return new CustomDocumentAggregationOperation(document);
}
public static List<AggregationOperation> of(#NonNull Document... documents) {
return Arrays.stream(documents)
.map(CustomDocumentAggregationOperation::of)
.collect(Collectors.toList());
}

Merging entity with Play! framework and JPA silently failed

I've been looking around and around without finding any topics related to my situation.
I'm using:
Play! framework v2.5.3 in Java
Hibernate EntityManager v5.1.0.Final
Hibernate JPA 2.1 API v1.0.0.Final
PostgreSQL 9.4
Here the route called with AJAX:
PUT /admin/entity/:id
Which is bound to:
controllers.Entity.update(id: Long)
Here how I handle the update request:
#play.db.jpa.Transactional
public Result update(final long id) {
EntityManager em = _jpa.em("default");
DynamicForm form = _formFactory.form().bindFromRequest();
models.Entity entity;
entity = em.find(models.Entity.class, id);
if (entity == null)
return badRequest();
entity.update(em, form);
em.merge(entity);
return ok();
The method update of Entity change values of the class attributes which are basically String attributes.
My issue: nothing get updated while still executing this piece of code.
I enable SQL log which only display the SELECT query corresponding to em.find() method call. Nothing related to an UPDATE query.
I've been using JPA/EntityManager with Play! for others projects (but with lower version of the framework) without facing this kind of problem.
Any idea why nothing get merged ?
I've been able to fix this issue by writing following piece of code inside
models.Entity.update:
em.getTransaction.begin();
Query query = em.createQuery("UPDATE entity SET value = :v WHERE id = :id");
query.setParameter("value", value);
query.setParameter("id", id);
query.executeUpdate();
em.getTransaction.commit();
But even if this is working, that's not the way how thing should be done... It
doesn't make coffee at all!
Edit: this solution do not work anymore....
I really don't know what I'm doing bad, if any body has an idea about this issue, you're help would be much appreciated.

testNG: sending report via mail within the #AfterSuite section

I'd like to send the report generated by testNG ( java+eclipse+testNG) within the #AfterSuite section.
It's not a problem to send it, but the point is that the report is generated after the #AfterSuite section, so , basically, i send the previous one instead of the last one !
Any idea about how can I solve it ?
As you are seeing, #AfterSuite runs before the report is generated.
Have you though about implementing a TestNG IReporter listener ?
public class MyReporter implements IReporter {
#Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> iSuites, String s) {
//Create your bespoke results
//Email results
}
}
Obviously you can see a flaw in that you have to generate your own results from the raw results data (which may be advantageous if you just want to email a subset of data).
The ideal solution would to be able to extend the default report generator, but I am not sure this can be done. However there is an existing listener provided by http://reportng.uncommons.org/, which actually provides a much nicer report output.
If you extend this this class, and call their code, and then add email generator code afterwards, it may work
public class MyReporter extends HTMLReporter {
#Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> iSuites, String s) {
super.generateReport(xmlSuites, iSuites, s);
//Email results
}
}
You can attach a listener to a test suite in several ways, as explained on the TEstNG website (http://testng.org/doc/documentation-main.html#listeners-testng-xml)
An alternative to all of this woudl be to use a build tool like Maven to run your tests, then have a post test event to email the results.
I copied the answer from Krishnan.
It works for me.
By the way, in my test environment, I need to extends the org.testng.reporters.EmailableReporter2 instead of EmailableReporter to make sure the correct count.
See below for your reference:
Krishnan Mahadevan Krishnan Mahadevan at Jul 31, 2012 at 8:58 am I am guessing that you are referring to the TestNG generated
"emailable-report.html" which you would want to mail.
With that assumption here's how you should be able to do it.
Extend org.testng.reporters.EmailableReporter
Override org.testng.reporters.EmailableReporter.generateReport(List,
List, String) and have it do something as below :
#Override
public void generateReport(List xml, List suites, String
outdir) {
super.generateReport(xml, suites, outdir);
SendFileEmail e= new SendFileEmail();
e.sendEmail();
}
Now add up this listener of yours into your suite file using
tag.

Dynamic mask data for web project

Currently our web projects need to anonymize some data.
(for example a security number like 432-55-1111 might appear as 432-55-**)
These datas may contain email, id, price, date ,and so on.
The tables' name and columns that needed to be masked was saved in DB.
We are using spring security to judge a user whether he can see the data or not.
The data domain object(CMP) may be get from SQL or JPQL(named query or native query)or JPA Load method or Mainframe.
We need to find a best efficient way (not the DB end) to mask these data dynamically.
If we use a interceptor at the EJB method end , we need to annotation all the Object(DTO)
and all the columns. That's may be low efficiency.
Any body know how can we invoke a method(like a interceptor) when finish SQL executed and named query(native query) exectued, and we can call a method to mask the result by the query and user id.
Or other ways.
It would be good to have this in the lowest level, so that other applications like reporting would not need a separate solution.
Our project's architecture is JSF+Spring+EJB 3.0+JPA 1.0.We have many web projects.For JPA some projects using EclipseLink 2.2 ,some using Hibernate.
UPDATE:
More information about our projects. We have many web project about different feature.So we have many ejb projects associated with them. Every ejb has DAO to get their CMP by call JPQL or get(class, primarykey) metod.Like below:
Query query = em.createNamedQuery(XXXCMP.FIND_XXX_BY_NAME);
query.setHint(QueryHints.READ_ONLY, HintValues.TRUE);
query.setParameter("shortName", "XXX").getSingleResult();
Or
XXXCMP screen = entityManager.find(XXXCMP.class, id);
The new EJB services code converter to transfrom the data from CMP to DTO.
The converter as below:
/**
* Convert to CMP.
*
*/
CMP convertToCMP(DTO dto, EntityManager em);
/**
* Convert CMP to domain object with all fields populated, the default scenario is
* <code>EConvertScenario.Detail</code>.
*
*/
DTO convertFromCMP(CMP cmp, EntityManager em);
But some old services use their own methods to convert CMP.Also some domain services used for search lazy paing, they also don't use the converter.
We want to mask the data before the CMP convert to DTO.
You can try EntityListener to intercept entity loading into the persistence context with #PostLoad annotation.
Else, can try within accesor methods(getter/setter) which I think is suitable for masking/formatting etc.
Edit : (based on comments & question update)
You can share entity/DTO across appications
public String getSomethingMasked(){
return mask(originalString);
}
The data retrieval pattern isn't uniform across applications. If all the applications are using same database, it must be generalized. There is no point of writing same thing again with different tools. Each application might apply business logic afterwards.
Probably, you can have a separate project meant for interacting with database & then including it in other applications for further use. So it will be a common point to change anything, debug, enhance etc.
You are using Eclipselink, Hibernate & other custom ways for fetching data & you require minimal workaround, which from my perspective seems difficult.
Either centralize the data retrieval or make changes all over separately if possible, which I think is not feasible, compromising consistency.
In this case, you may intercept the JSF's conversion fase. This solution applies to JSF views, not to reportings.
#FacesConverter("AnonymizeDataConverter")
public class AnonymizeDataConverter implements Converter{
#Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
return getAnonymisedData(value);
}
#Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
return getAnonymisedData(value);
}
public static String getAnonymisedData(Object data) {
if (data == null)
return "";
String value = data.toString().trim();
if (!value.isEmpty())
return value.substring(0, value.lenght() - 4) + "**";
return "";
}
}

GWT Editor Framework: Drop Down List

I'm looking for someone to point me in the right direction (link) or provide a code example for implementing a drop down list for a many-to-one relationship using RequestFactory and the Editor framework in GWT. One of the models for my project has a many to one relationship:
#Entity
public class Book {
#ManyToOne
private Author author;
}
When I build the view to add/edit a book, I want to show a drop down list that can be used to choose which author wrote the book. How can this be done with the Editor framework?
For the drop-down list, you need a ValueListBox<AuthorProxy>, and it happens to be an editor of AuthorProxy, so all is well. But you then need to populate the list (setAcceptableValues), so you'll likely have to make a request to your server to load the list of authors.
Beware the setAcceptableValues automatically adds the current value (returned by getValue, and defaults to null) to the list (and setValue automatically adds the value to the list of acceptable values too if needed), so make sure you pass null as an acceptable value, or you call setValue with a value from the list before calling setAcceptableValues.
I know it's an old question but here's my two cents anyway.
I had some trouble with a similar scenario. The problem is that the acceptable values (AuthorProxy instances) were retrieved in a RequestContext different than the one the BookEditor used to edit a BookProxy.
The result is that the current AuthorProxy was always repeated in the ValueListBoxwhen I tried to edit a BookProxy object. After some research I found this post in the GWT Google group, where Thomas explained that
"EntityProxy#equals() actually compares their request-context and stableId()."
So, as I could not change my editing workflow, I chose to change the way the ValueListBox handled its values by setting a custom ProvidesKey that used a different object field in its comparison process.
My final solution is similar to this:
#UiFactory
#Ignore
ValueListBox<AuthorProxy> createValueListBox ()
{
return new ValueListBox<AuthorProxy>(new Renderer<AuthorProxy>()
{
...
}, new ProvidesKey<AuthorProxy>()
{
#Override
public Object getKey (AuthorProxy author)
{
return (author != null && author.getId() != null) ? author.getId() : Long.MIN_VALUE;
}
});
}
This solution seems ok to me. I hope it helps someone else.