Is it possible to use Native SQL queries using micronaut hibernate-gorm? - sql

I've created micronaut project using hibernate-gorm which gives me GORM and Groovy functionality but when it does not have groovy.sql.Sql class and if i inject DataSource then it's not working too. Is it possible to use native SQL queries with micronaut hiberate-gorm?

Yes, it is possible. See the example:
import grails.gorm.annotation.Entity
import grails.gorm.hibernate.HibernateEntity
#Entity
class Planet implements HibernateEntity<Planet> {
String name
}
In this case it is important to implement HibernateEntity and then you will have findWithSql method available as it is shown in the unit test below implemented using Spock framework:
import grails.gorm.transactions.Transactional
import io.micronaut.test.annotation.MicronautTest
import spock.lang.Specification
#MicronautTest
class PlanetSpec extends Specification {
#Transactional
void 'Planet is found when using native query'() {
given:
new Planet(name: 'Mars').save()
new Planet(name: 'Earth').save(flush: true)
when:
def actual = Planet.findWithSql("select * from planet p where p.name = 'Mars'")
then:
actual.name == 'Mars'
}
}

I know that there is a SQLQuery method in hibernate that runs native query against database engine. have you tried it?

Related

Why doesn't intellij suggest org.mockito.Mockito dependency when using verify()?

When creating a new test, I have issues importing mockito methods into the class.
The class looks like
#ExtendWith(SpringExtension.class)
#SpringBootTest(classes = MainSpringBootApplication.class)
class CoolServiceTest {
#Autowired
SomeService someService;
#Test
void testGetInstitutionsCache_ShouldNotSecondTime() {
assertEquals(someService.getName(), "bob");
verify(idsClientMock, times(1));
}
}
In the import menu of intellij I don't see the option to import org.mockito.Mockito which I know where the package resides.
Instead I get the option to add;
import static org.testcontainers.shaded.com.google.common.base.Verify.verify;
(obviously not what I want)
I can get around it by typing the full Mockito.verify and then adding an on-demand static import to tidy the code.
The package is definitely installed and available to use, but intellij won't pick it up automatically.

Initialize JsonB configuration once

I am customizing Jsonb using a ContextResolver<Jsonb> as in the example below.
It works correctly, but I have seen that the method gets invoked on every call which seems to me a waste of performance. ¿Isn't there a way to initialize Jsonb only once?
#Override
public Jsonb getContext(Class type) {
final JsonbConfig config = new JsonbConfig()
.withDateFormat(dateFormat, Locale.getDefault())
.withSerializers(
new UserSerializer(),
new PaperSerializer()
);
return JsonbBuilder.create(config);
}
PS: I am aware I can setup serializers using #JsonbTypeSerializer. I am not looking for alternative ways to do the same configuration.
You need to store the instance of Jsonb in your context resolver yourself. Probably with a volatile and a double checked locking to be on the safe side.
I'm not entirely sure if it's a bug or a feature (i.e. if it's the desired behavior that you have to do it yourself and that it's delegated to the ContextResolver for each call).
See the implementation here: https://github.com/resteasy/Resteasy/blob/master/providers/json-binding/src/main/java/org/jboss/resteasy/plugins/providers/jsonb/AbstractJsonBindingProvider.java#L27 .
I'll check with the RESTEasy developers.
There is now a new way to customize JSON-B with Quarkus, it is documented here: https://quarkus.io/guides/rest-json-guide#configuring-json-support
So the correct answer is now to implements a JsonbConfigCustomizer.
The following should works for your use case:
import io.quarkus.jsonb.JsonbConfigCustomizer;
import javax.inject.Singleton;
import javax.json.bind.JsonbConfig;
import javax.json.bind.serializer.JsonbSerializer;
#Singleton
public class MyJsonbConfigCustomizer implements JsonbConfigCustomizer {
public void customize(JsonbConfig config) {
config.withDateFormat(dateFormat, Locale.getDefault())
.withSerializers(
new UserSerializer(),
new PaperSerializer()
);
}
}

How to access test method annotations from a TestExecutionListener

I'm trying to port Test Management For Jira JUnit Integration to JUnit5. This module generates a JSON report of the test run and associates the results with Jira tickets by using annotations on the test methods, example.
From the TestExecutionListener I'm not sure what the best approach to retrieve the TestCase annotation is.
I looked at Reflection using the TestIdentifier.getSource and doing manipulations to rebuild the method signature and extracting the annotation from there but the approach felt clumsy.
I came across this post Allow extensions to register TestExecutionListeners which proposed the following:
Proposal: Have your extension publish the WebDriver bean's session id, e.g.
String sessionId = ...;
extensionContext.publishReportEntry("webDriverSessionId", sessionId)
In your TestExecutionListener, implement reportingEntryPublished and store it in a Map with the TestIdentifier as a key. In executionFinished report the test outcome along with the value from this Map.
This approach looks promising but I want to make sure there isn't another way that doesn't require both an extension and a test execution listener. Is there a way to retrieve test method annotation information directly in the TestExecutionListener?
#Alex, the following might be used inside the listener...
((MethodSource) testIdentifier.source).javaMethod.getAnnotation(TestCase.class)
Seems like you can't get test annotation from TestExecutionListener but instead you can implement TestWatcher or e.g AfterEachCallback and get custom annotation value like that:
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestWatcher;
public class MyExtention implements TestWatcher, AfterEachCallback {
#Override public void testSuccessful(ExtensionContext context) {
if (context.getElement().isPresent() && context.getElement().get().isAnnotationPresent(MyCustomAnnotation.class)) {
int val = context.getElement().get().getAnnotation(MyCustomAnnotation.class).value();
// Report on success
}
}
#Override public void afterEach(ExtensionContext context) throws Exception {
if (context.getElement().isPresent() && context.getElement().get().isAnnotationPresent(MyCustomAnnotation.class)) {
int val = context.getElement().get().getAnnotation(MyCustomAnnotation.class).value();
// Report each
}
}
}

What is `static inject...`

I found this line of code in Aurelia Dialog
static inject = [DialogService];
This is the full class:
import {Prompt} from './prompt';
import {DialogService} from '../dialog-service';
export class CommonDialogs {
static inject = [DialogService];
constructor(dialogService){
this.dialogService = dialogService;
}
prompt(question){
return this.dialogService.open({viewModel:Prompt, model:question});
};
}
What is the static inject doing? I get that it is injecting the dialog service into the constructor. But why do it this way instead of the usual inject?
As the blog post you linked to mentions, static inject was the original way to do dependency injection. Once Babel started supporting decorators, we implemented the inject decorator to make Aurelia code look a little nicer. Under the covers, it simply adds the inject property to the class at runtime (https://github.com/aurelia/dependency-injection/blob/master/src/decorators.js#L13).

Can Jython-based Java classes from an Eclipse PyDev project code be referenced by an Eclipse plugin project?

The following explains my attempts at trying to make a hybrid PyDev/Eclipse plugin project. I have since discovered that even if I make a separate PyDev project, I cannot use my PyDev Jython-based Java classes by referencing the project in a plug-in project. On the other hand, I can use the PyDev Java classes in a separate project that is NOT a plugin project.
I've got an eclipse plugin that I've also set as a PyDev project. I built it based on Jython Book v1.0 documentation chapter 10 and chapter 11.
When I run Main as seen below, I see
1 BUIDING-A 100 MAIN ST
When I try to do the same thing within a plug-in project that is set as a PyDev project (right click on project->Pydev->Set as Pydev Project), I get an ImportError: no module named Building. It seems like the plugin nature of the project is trumping the PyDev nature of the project.
Any ideas?
I've put the Main function below followed by some support code.
package org.jython.book;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jython.book.interfaces.BuildingType;
import org.jython.book.util.JythonObjectFactory;
public class Main {
public static void main(String[] args) {
// Obtain an instance of the object factory
JythonObjectFactory factory = JythonObjectFactory.getInstance();
// Call the createObject() method on the object factory by
// passing the Java interface and the name of the Jython module
// in String format. The returning object is casted to the the same
// type as the Java interface and stored into a variable.
BuildingType building = (BuildingType) factory.createObject(
BuildingType.class, "Building");
// Populate the object with values using the setter methods
building.setBuildingName("BUIDING-A");
building.setBuildingAddress("100 MAIN ST.");
building.setBuildingId(1);
System.out.println(building.getBuildingId() + " " + building.getBuildingName() + " " +
building.getBuildingAddress());
}
}
Here is the JythonObjectFactory which should be exactly like what is in [Jython Book v1.0 documentation chapter 10][3], with typos corrected, of course :-)
package mypackage.files.util;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
/**
* Object factory implementation that is defined
* in a generic fashion.
*
*/
public class JythonObjectFactory {
private static JythonObjectFactory instance = null;
private static PyObject pyObject = null;
protected JythonObjectFactory() {
}
/**
* Create a singleton object. Only allow one instance to be created
*/
public static JythonObjectFactory getInstance(){
if(instance == null){
instance = new JythonObjectFactory();
}
return instance;
}
/**
* The createObject() method is responsible for the actual creation of the
* Jython object into Java bytecode.
*/
public static Object createObject(Object interfaceType, String moduleName){
Object javaInt = null;
// Create a PythonInterpreter object and import our Jython module
// to obtain a reference.
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("from " + moduleName + " import " + moduleName);
pyObject = interpreter.get(moduleName);
try {
// Create a new object reference of the Jython module and
// store into PyObject.
PyObject newObj = pyObject.__call__();
// Call __tojava__ method on the new object along with the interface name
// to create the java bytecode
javaInt = newObj.__tojava__(Class.forName(interfaceType.toString().substring(
interfaceType.toString().indexOf(" ")+1,
interfaceType.toString().length())));
} catch (ClassNotFoundException ex) {
Logger.getLogger(JythonObjectFactory.class.getName()).log(Level.SEVERE, null, ex);
}
return javaInt;
}
}
If you have multiple natures added to the project, all builders related to those projects will be invoked by Eclipse. So if the build fails with some PyDev related error message, this really indicates a problem with the PyDev part, not with PDE. Maybe you are missing some additional files or project settings for that project?
Generally speaking, you should avoid mixing multiple natures in one project. This often leads to trouble, because most builders and other extensions expect that they are "the one and only" tinkering with a project. And almost all use cases involving multiple natures can more easily be solved by having two different projects, where one project references the other project (and can then access resources of that referenced project). See Project properties -> Referenced Projects for that.