How to access datetime field outside of transaction with kotlin exposed - kotlin

I've got an exposed DAO-style setup with a datetime-column and want to access it after I received the row from the schema.
Table:
object Entries : IntIdTable() {
val date = datetime(name = "date").nullable()
}
Entity:
class Entry(id: EntityID<Int>) : IntEntity(id) {
companion object : EntityClass<Entry>(Entries)
var date by Entries.date
}
DAO:
object DB {
private val pool = BasicDataSource()
private val database: Database
init {
pool.url = "jdbc:mysql://127.0.0.1:3306/test"
pool.driverClassName = "com.mysql.cj.jdbc.Driver"
pool.username = "user"
pool.password = "secret"
pool.minIdle = 5
pool.maxIdle = 10
database = Database.connect(pool)
}
infix fun <T> query(block: DB.() -> T): T {
return transaction {
block.invoke(this#DB)
}
}
}
Main:
fun main() {
val entry = DB.query {
Entry.all().single() // There is only one row at this point
}
println(entry.date) //! Error is thrown on this line
}
It throws a java.lang.IllegalStateException: No transaction in context.. When I move the println into the transaction, it works as expected. If I change the type of the column to varchar and expect a string it works in both cases.
How can I get the date outside of the transaction? I think it worked a few versions back, but I'm unsure.

I solved the problem by updating the Exposed dependencies to the latest version, which has a new naming pattern.
Old dependencies:
<dependency>
<groupId>org.jetbrains.exposed</groupId>
<artifactId>exposed</artifactId>
<version>0.17.14</version>
</dependency>
New dependencies:
<dependency>
<groupId>org.jetbrains.exposed</groupId>
<artifactId>exposed-core</artifactId>
<version>0.36.1</version>
</dependency>
<dependency>
<groupId>org.jetbrains.exposed</groupId>
<artifactId>exposed-dao</artifactId>
<version>0.36.1</version>
</dependency>
<dependency>
<groupId>org.jetbrains.exposed</groupId>
<artifactId>exposed-jdbc</artifactId>
<version>0.36.1</version>
</dependency>
<dependency>
<groupId>org.jetbrains.exposed</groupId>
<artifactId>exposed-java-time</artifactId>
<version>0.36.1</version>
</dependency>
Looks a little more bloated, but I guess it's cleaner to not have every possible module of Exposed loaded every time.
Side note:
I needed to update some imports (IntIdTable, EntityId, etc. and datetime are now located in new packages) and replace Entries.date eq null by Entries.date.isNull() in queries.

Related

How to exclude mutations from Query root node with spqr?

I use io.leangen.graphql.spqr library version 0.9.6 and I need to exclude mutations from Query root node into the Doc.
My GraphQLController.kt looks this way:
#RestController
class GraphQLController {
private var graphQL: GraphQL? = null
#Autowired
fun GraphQLController(bookGraph: BookGraph) {
val schema = GraphQLSchemaGenerator()
.withResolverBuilders(
AnnotatedResolverBuilder(),
PublicResolverBuilder("com.example.graphql.spqr"))
.withOperationsFromSingleton(bookGraph)
.withValueMapperFactory(JacksonValueMapperFactory())
.generate()
graphQL = GraphQL.newGraphQL(schema)
.build()
}
#PostMapping(value = ["/graphql"], consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE], produces = [MediaType.APPLICATION_JSON_UTF8_VALUE])
#ResponseBody
fun execute(#RequestBody request: Map<String?, Any?>): ExecutionResult? {
return graphQL!!.execute(ExecutionInput.newExecutionInput()
.query(request["query"] as String?)
.variables(request["variables"] as Map<String, Object>?)
.operationName(request["operationName"] as String?)
.build())
and my BookGraph.kt looks this way:
#Component
class BookGraph {
#Autowired
private lateinit var bookService: BookService
#GraphQLQuery(name = "books")
fun books() : List<Book> {
return bookService.findAll()
}
#GraphQLMutation(name = "createBook")
fun createBook(#GraphQLInputField(name = "name") name: String) : Book {
return bookService.findAll()
}
}
How can I do it?
I searched for possible solutions both in StackOverflow and SPQR issues but cannot find a solution.
Example of Query root node below, I want to exclude createBook:
While I want Mutation root node to remain untouched:
It's bug. You're using a very old version of SPQR (Feb. 2018). This has been fixed a long long time ago. Please try to follow the releases as much as possible, as lots of things are getting fixed and improved.
It is possible to work around the bug by customizing the ResolverBuilders, but I wouldn't recommend going that route.
The Spring Starter (if even relevant to you) is currently lagging behind (not yet on the latest SPQR version) but I'm actively working on the new release. Should be out very soon.
Btw, your setup has a lot of redundancy. Can be simplified to:
val schema = GraphQLSchemaGenerator()
.withOperationsFromSingleton(bookGraph)
//replace with your own root package(s)
.withBasePackages("com.example.graphql.spqr")
.generate()

How to get all properties with the ids

I'm new to all the graph database stuff and I'm having a hard time with some basic queries.
I'm using Gremlin with Kotlin to connect to AWS Neptune.
I want to get all my vertex properties including the Id.
I have added an vertex with:
g.addV("foo")
.property("name", "Foo 1")
.next()
And to retrieve the properties I have tried:
g.V()
.hasLabel("foo")
.valueMap<String>()
.by(unfold<String>())
.forEach {
// val name = it["name"] -> works great!
// val id = it["id"] -> doesn't exist
}
In this first approach I get a map for each item but this map does not contain the ID.
g.V()
.hasLabel("foo")
.forEach {
// it is an ReferenceVertex that has an ID!
val name = it.property<String>("name") // This returns an EmptyVertexProperty, so I can't read the name
}
I'm using
<dependency>
<groupId>org.apache.tinkerpop</groupId>
<artifactId>gremlin-driver</artifactId>
<version>3.4.4</version>
</dependency>
Bonus question
I couldn't figure out (nor find in the documentation) what the generics on valueMap and unfold method do. Kotlin does not allow me to ommit them (as I have seem in some java code...?), but changing them to Int, for instance, changes nothing in the outcome for these examples... So what is it for? D:
Thanks in advance!
If you want to get the Id with all the other properties you need to run valueMap().with(WithOptions.tokens) or you can use elementMap().

How to import JunitParamsRunner in Java class

it is my first day with JUnit. I try to make test with parameters. I have code:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import static org.junit.Assert.assertEquals;
#RunWith(JUnitParamsRunner.class)
public class MoneyParameterizedTest {
private static final Object[] getMoney() {
return new Object[] {
new Object[] {10, "USD"},
new Object[] {20, "EUR"}
};
}
#Test
#Parameterized.Parameters(method = "getMoney")
public void constructorShouldSetAmountAndCurrency(
int amount, String currency) {
Money money = new Money(amount, currency);
assertEquals(amount, money.getAmount());
assertEquals(currency, money.getCurrency());
}
}
IntelliJ told me that: Can't resolve symbol JUnitParamsRunner and method. Is it problem with import? My class which I'm testing is in the same package.
----- EDIT -------
I change JunitParamsrunner.class to Parameterized.class and it's okay but problem with symbol 'method' in Parametrized.Parameters is the same.
JUnitParams (licensed Apache 2.0) is a separate library, which means it's not shipped with JUnit itself. This also means that you need to make sure it's in the classpath of your project. If you're using maven (or something similar) then it's rather easy, you just need to add it as a dependency in your pom and make sure IJ has picked up the changes (wither automatically or manually if it shows a pop-up in the upper right corner):
<dependency>
<groupId>pl.pragmatists</groupId>
<artifactId>JUnitParams</artifactId>
<version>1.0.5</version>
<scope>test</scope>
</dependency>
Otherwise, download it yourself (click the Download ( JAR ) link) and the library it to your classpath.
Please note that, although the concepts are similar, Parameterized is not the same thing with JUnitParams, the latter trying to simplify and improve the way you can write parametrized JUnit tests.
P.S.: There's another library called Zohhak which seems even more flexible than JUnitParams but it's released under LGPL 3.0 so it depends on your license restrictions.
Here's an example that should work:
import junitparams.JUnitParamsRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
//import org.junit.runners.Parameterized.Parameters;
import static org.junit.Assert.assertEquals;
import junitparams.Parameters;
#RunWith(JUnitParamsRunner.class)
public class MoneyTest {
private final static int VALID_AMOUNT = 5;
private final static String VALID_CURRENCY = "USD";
private static final Object[] getInvalidAmount() {
return new Integer[][] {{-12387}, {-5}, {-1}};
}
#Test(expected = IllegalArgumentException.class)
#Parameters(method = "getInvalidAmount")
public void constructorShouldThrowIAEForInvalidAmount(int invalidAmount){
new Money(invalidAmount, VALID_CURRENCY);
}
private static final Object[] getInvalidCurrency(){
return new String[][]{{null}, {""}};
}
#Test(expected = IllegalArgumentException.class)
#Parameters(method = "getInvalidCurrency")
public void constructorShouldThrowIAEForInvalidCurrency(String invalidCurrency){
new Money(VALID_AMOUNT, invalidCurrency);
}
private static final Object[] getMoney() {
return new Object[] {
new Object[] {10, "USD"},
new Object[] {20, "EUR"}
};
}
#Test
#Parameters(method = "getMoney")
public void constructorShouldSetAmountAndCurrency(
int amount, String currency) {
Money money = new Money(amount, currency);
assertEquals(amount, money.getAmount());
assertEquals(currency, money.getCurrency());
}
}
your POM.xml should like this ...
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
<groupId>groupId</groupId>
<artifactId>JUnit</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>pl.pragmatists</groupId>
<artifactId>JUnitParams</artifactId>
<version>1.0.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>pl.pragmatists</groupId>
<artifactId>JUnitParams</artifactId>
<version>1.0.5</version>
<scope>compile</scope>
</dependency>
</dependencies>

Serializing Joda DateTime with Jackson and Spring

I am having problems consistently serializing and deserializing a Joda DateTime from java to json and back again using Spring Boot and Jackson-databind 2.5.2. My pom.xml looks like this.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>
When I serialize the DateTime object I get an integer representing the DateTime. Not what I expected actually, but fine. BUT when I go to save my object back I get the following error...
Failed to convert property value of type 'java.lang.String' to required type 'org.joda.time.DateTime' for property 'endTime';
nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type org.joda.time.DateTime for value '1428600998511'
For some reason it is serializing it to an integer but then deserializing it as if it's a string, which it is not. I also tried setting the endTime = new Date(intValue) before calling the rest service and that also failed trying to convert a string like 'Tue Apr 28 2015 00:00:00 GMT-0700 (PDT)' to a DateTime.
What am I doing wrong?
UPDATE:
Here is the JSON that I GET and that I try to immediately POST right back.
{
id: 4,
username: "",
name: "eau",
email: "aoue",
verbatimLocation: null,
latitude: null,
longitude: null,
startTime:null,
endTime: 1429034332312,
description: "ueoa",
media: [ ],
timeSubmitted: 1428600998000,
status: null,
submissionid: null
}
For a more re-usable mechanism, you can create a JsonSerializer:
/**
* When passing JSON around, it's good to use a standard text representation of
* the date, rather than the full details of a Joda DateTime object. Therefore,
* this will serialize the value to the ISO-8601 standard:
* <pre>yyyy-MM-dd'T'HH:mm:ss.SSSZ</pre>
* This can then be parsed by a JavaScript library such as moment.js.
*/
public class JsonJodaDateTimeSerializer extends JsonSerializer<DateTime> {
private static DateTimeFormatter formatter = ISODateTimeFormat.dateTime();
#Override
public void serialize(DateTime value, JsonGenerator gen, SerializerProvider arg2)
throws IOException, JsonProcessingException {
gen.writeString(formatter.print(value));
}
}
Then you can annotate your get methods with:
#JsonSerialize(using = JsonJodaDateTimeSerializer.class)
This gives you consistent formatting throughout your application, without repeating text patterns everywhere. It's also timezone aware.
In the end I was able to do as beerbajay said and use ...
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss.SSSZ")
... to serialize my date. I did, though, end up going back to using a Long instead of a DateTime because dealing with the date on the javascript side was too troublesome. Finding a pattern that worked for jquery datepicker, joda DateTime, and for postgresql proved to be too much work for the little time I had.

ejb3.1 #Startup.. #Singleton .. #PostConstruct read from XML the Objects

I need to initialize a set of static String values stored in an XML files [ I know this is against the EJB spec ]
as shown below since the over all Idea is to not hardcore within EJB's the JNDI info
Utils.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="jndidb">java:jdbc/MYSQLDB10</entry>
<entry key="jndimdbque">java:jms/QueueName/remote</entry>
<entry key="jndi1">DBConnections/remote</entry>
<entry key="jndi2">AddressBean/remote</entry>
</properties>
The Onload of ejbserver startup code is as follows ...
inpstrem = clds.getClassLoaders(flename) Reads the Util.xml and stores the same in Hashtable key value pare....
package com.ejb.utils;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.Singleton;
import javax.ejb.Startup;
#Singleton
#Startup
public class StartupUtils {
private final String INITFILENAME = "/System/Config/Utils.xml";
private static Hashtable HTINITFLENME=null,HTERRINITFLENME=null,HTCMMNFLENME=null;
public StartupUtils() {
HTINITFLENME = new Hashtable();
HTERRINITFLENME = new Hashtable();
}
public void printAll(Hashtable htcmmnflenme){
Enumeration ENUMK = null, VALS = null;
String KEY = "", VALUE = "";
ENUMK = htcmmnflenme.keys();
while (ENUMK.hasMoreElements()) {
KEY = null;VALUE = null;
KEY = (ENUMK.nextElement().toString().trim());
VALUE = htcmmnflenme.get(KEY).toString().trim();
InitLogDisplay(KEY + " :::: " + VALUE);
}
}
public static void InitLogDisplay(String Datadisplay){
System.out.println(Datadisplay);
}
public Hashtable getDataProp(String flename){
Map htData = null;
InputStream inpstrem = null;
ClassLoaders clds = null;
Enumeration enumk = null, vals = null;
String key = "", value = "";
Properties props = null;
Hashtable htx = null;
try {
clds = new ClassLoaders();
inpstrem = clds.getClassLoaders(flename);
props = new Properties();
props.loadFromXML(inpstrem);
enumk = props.keys();
vals = props.elements();
htData = new HashMap();
htData = new TreeMap();
while (enumk.hasMoreElements()) {
key = (enumk.nextElement().toString().trim());
value = (vals.nextElement().toString().trim());
htData.put(key,value);
}
clds = null;
props = null;
inpstrem.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
key = ""; value = "";
enumk = null;vals = null;
clds=null;
props=null;
}
htx = new Hashtable();
htx.putAll(htData);
return htx;
}
public void setUtilsPropDetails(){
HTINITFLENME = getDataProp(INITFILENAME);
this.printAll(HTINITFLENME);
}
public static Hashtable getUtilsPropDetails(){
return HTINITFLENME;
}
#PostConstruct
public void startOnstartup(){
this.setUtilsPropDetails();
this.printAll();
}
#PreDestroy
public void startOnshutdown(){
try {
this.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
On startup of EJB server "this.printAll(HTINITFLENME);" prints the key values of the XML file hoever If an external Call is made via any other EJB's to the method "getUtilsPropDetails()" does not return the key values....
Am i doing something wrong ??????
Have you considered using the deployment descriptor and having the container do this work for you?
There are of course <resource-ref>, <resource-env-ref>, <ejb-ref> and <env-entry> elements to cover externally configuring which things should be made available to the bean for lookup. For example:
<resource-ref>
<res-ref-name>db</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<mapped-name>java:jdbc/MYSQLDB10</mapped-name>
</resource-ref>
I'm not sure how your vendor handles mapped-name (that particular element is vendor specific), but there will be an equivalent syntax to specify the datasource you want.
The singleton can then lookup java:comp/env/db and return the datasource to other EJBs.
If you are in a compliant Java EE 6 server, then you can change the name to <res-ref-name>java:app/db</res-ref-name> and then anyone in the app can lookup the datasource without the need to get it from the singleton. Global JNDI is a standard feature of Java EE 6 and designed for exactly this.
You can put those elements in the ejb-jar.xml, web.xml or application.xml. Putting them in the application.xml will make the one entry available to the entire application and give you one place to maintain everything.
Global resources can also be injected via:
#Resource(name="java:app/db")
DataSource dataSource;
If for some reason you didn't want to use those, at the very least you could use the <env-entry> element to externalize the strings.
EDIT
See this other answer for a much more complete description of JNDI as it pertains to simple types. This of course can be done where the name/value pairs are not simple types and instead are more complex types like DataSource and Topic or Queue
For example:
<resource-ref>
<res-ref-name>myDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
</resource-ref>
<resource-ref>
<res-ref-name>myJmsConnectionFactory</res-ref-name>
<res-type>javax.jms.ConnectionFactory</res-type>
</resource-ref>
<resource-ref>
<res-ref-name>myQueueCF</res-ref-name>
<res-type>javax.jms.QueueConnectionFactory</res-type>
</resource-ref>
<resource-ref>
<res-ref-name>myTopicCF</res-ref-name>
<res-type>javax.jms.TopicConnectionFactory</res-type>
</resource-ref>
<resource-env-ref>
<resource-env-ref-name>myQueue</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>
<resource-env-ref>
<resource-env-ref-name>myTopic</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
</resource-env-ref>
<persistence-context-ref>
<persistence-context-ref-name>myEntityManager</persistence-context-ref-name>
<persistence-unit-name>test-unit</persistence-unit-name>
</persistence-context-ref>
<persistence-unit-ref>
<persistence-unit-ref-name>myEntityManagerFactory</persistence-unit-ref-name>
<persistence-unit-name>test-unit</persistence-unit-name>
</persistence-unit-ref>
See the JNDI and simple types answer for look and injection syntax.
I see the name and type, but where's the value?
Configuring what actual things these names refer to has historically been done in a separate vendor specific deployment descriptor, such as sun-ejb-jar.xml or openejb-jar.xml or whatever that vendor requires. The vendor-specific descriptor and the standard ejb-jar.xml descriptor combined provide the guaranteed portability apps require.
The ejb-jar.xml file offering only standard things like being able to say what types of resources the application requires and what names the application has chosen to use to refer to those resources. The vendor-specific descriptor fills the gap of mapping those names to actual resources in the system.
As of EJB 3.0/Java EE 5, we on the spec groups departed from that slightly and added the <mapped-name> element which can be used in the ejb-jar.xml with any of the references shown above, such as <resource-ref>, to the vendor-specific name. Mapped name will never be portable and its value will always be vendor-specific -- if it is supported at all.
That said, <mapped-name> can be convenient in avoiding the need for a separate vendor-specific file and achieves the goal of getting vendors-specific names out of code. After all, the ejb-jar.xml can be edited when moving from one vendor to another and for many people that's good enough.