Groovy shows java.io.NotSerializableException when making prepared statement - sql

When executing the following piece of code:
def xml = new XmlSlurper().parse(url)
title = rss.chanel.title
rss.channel.item.each {
sql.firstRow("SELECT COUNT(*) FROM news WHERE title = ? ", [it.title])
}
I get the following error:
Invalid argument value: java.io.NotSerializableException
What may cause it?

The problem was that it.title was a NodeChild object.
In order to get the serializable text of this object I had to use it.title.text(). It was quite tricky since I could use print it.title successfully

Related

kotlin exposed failed (insert is successful, but select is failure)

thanks reading this question.
I created simple kotlin project and I want to learn kotlin exposed.
I use H2 database.
I wrote code like below.
package learn.exposed.tables
import org.jetbrains.exposed.sql.Table
object AuthorTable : Table("author") {
val name = varchar("name", 30)
}
fun main() {
// this url based on http://www.h2database.com/html/features.html#execute_sql_on_connection
val url = "jdbc:h2:mem:test;INIT=runscript from 'classpath:/create.sql'\\;runscript from 'classpath:/init.sql'"
Database.connect(url, driver = "org.h2.Driver", user = "root", password = "")
transaction {
AuthorTable.insert {
it[name] = "hoge"
}
println("insert done.") // this message can show on console. I think Insert is successfull.
}
transaction {
AuthorTable.selectAll().firstOrNull()
}
}
and sql files below.
create table author (name varchar(30));
insert into author values ('author1');
When execute main(), console showing insert done.. in short, I think insert is doing well, but when execute AuthorTable.selectAll().firstOrNull(), happend Exception like below,
Exception in thread "main" org.jetbrains.exposed.exceptions.ExposedSQLException: org.h2.jdbc.JdbcSQLNonTransientException: 一般エラー: "java.lang.NullPointerException"
General error: "java.lang.NullPointerException" [50000-200]
SQL: [Failed on expanding args for SELECT: org.jetbrains.exposed.sql.Query#27406a17]
at org.jetbrains.exposed.sql.statements.Statement.executeIn$exposed_core(Statement.kt:62)
at org.jetbrains.exposed.sql.Transaction.exec(Transaction.kt:135)
at org.jetbrains.exposed.sql.Transaction.exec(Transaction.kt:121)
at org.jetbrains.exposed.sql.AbstractQuery.iterator(AbstractQuery.kt:65)
at kotlin.collections.CollectionsKt___CollectionsKt.firstOrNull(_Collections.kt:267)
at learn.exposed.MainKt$main$2.invoke(Main.kt:22)
at learn.exposed.MainKt$main$2.invoke(Main.kt)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.inTopLevelTransaction$run(ThreadLocalTransactionManager.kt:179)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.access$inTopLevelTransaction$run(ThreadLocalTransactionManager.kt:1)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$inTopLevelTransaction$1.invoke(ThreadLocalTransactionManager.kt:205)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.keepAndRestoreTransactionRefAfterRun(ThreadLocalTransactionManager.kt:213)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.inTopLevelTransaction(ThreadLocalTransactionManager.kt:204)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt$transaction$1.invoke(ThreadLocalTransactionManager.kt:156)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.keepAndRestoreTransactionRefAfterRun(ThreadLocalTransactionManager.kt:213)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction(ThreadLocalTransactionManager.kt:126)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction(ThreadLocalTransactionManager.kt:123)
at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManagerKt.transaction$default(ThreadLocalTransactionManager.kt:122)
at learn.exposed.MainKt.main(Main.kt:21)
at learn.exposed.MainKt.main(Main.kt)
can I solve this? do you know something how to solve this?
thanks.
Seems like you need at least one Primary Key(PK) or Constraint because of H2 bug.
https://github.com/h2database/h2database/issues/2191
https://github.com/JetBrains/Exposed/issues/801

DBArrayList to List<Map> Conversion after Query

Currently, I have a SQL query that returns information to me in a DBArrayList.
It returns data in this format : [{id=2kjhjlkerjlkdsf324523}]
For the next step, I need it to be in a List<Map> format without the id: [2kjhjlkerjlkdsf324523]
The Datatypes being used are DBArrayList, and List.
If it helps any, the next step is a function to collect the list and then to replace all single quotes if any [SQL-Injection prevention]. Using:
listMap = listMap.collect() { "'" + Util.removeSingleQuotes(it) + "'" }
public static String removeSingleQuotes(s) {
return s ? s.replaceAll(/'"/, '') : s
}
I spent this morning working on it, and I found out that I needed to actually collect the DBArrayList like this:
listMap = dbArrayList.collect { it.getAt('id')}
If you're in a bind like I was and restrained to a specific schema this might help, but #ou_ryperd has the correct answer!
While using a DBArrayList is not wrong, Groovy's idiom is to use the db result as a collection. I would suggest you use it that way directly from the db:
Map myMap = [:]
dbhandle.eachRow("select fieldSomeID, fieldSomeVal from yourTable;") { row ->
map[row.fieldSomeID] = row.fieldSomeVal.replaceAll(/'"/, '')
}

Exposed Kotlin. Problem with cyrillic encoding

I tryed to fix a problem with encodings. So, I sent from 'Postman', from web browser request to server, where I search data in database by keys in request. Request can be like this:
http://localhost:8080/books.getBooksByGenre/Документальное/0/10
(in browser).
Server receive string, like
http://localhost:8080/books.getBooksByGenre/%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5/0/10
then, takes params from url:
genreName: 'Документальное'
start: 0
count: 10.
Then, this data sends to dao:
override fun findGenreByName(genreName: String): DatabaseGenre {
return transaction(db) { getGenreByName(genreName) }
}
private fun getGenreByName(genreName: String): DatabaseGenre {
return try {
val foundGenre = GenreEntity.find { Genres.genre eq genreName }.single()
DatabaseGenre(foundGenre.id.value, foundGenre.genre, foundGenre.link)
} catch (e: Exception) {
throw NothingFoundInDatabaseException("no one genre found by '$genreName'")
} catch (e: NoSuchElementException) {
val m = "Duplicates of genre with name '$genreName'"
throw DuplicatedDataInDatabaseException(m)
}
}
In log I see, that sql-query for finding genres is correct, but I receive an exception:
java.util.NoSuchElementException: Collection is empty.
The sql-query, as I said, is correct:
SELECT genres.id, genres.genre, genres.link FROM genres WHERE genres.genre = 'Документальное'
Structure of genres table:
genres
id: int(10)
genre: varchar(100)
link: varchar(100
I tryied, to select all genres, and this query executed almost correctly. So, I decided, to check this query with english word, and this query correctly executed:
SELECT genres.id, genres.genre, genres.link FROM genres WHERE genres.genre = 'simpleGenre'
I have not exceptions with this query.
So, what I've done wrong and how to fix problem with collations?
UPD:
As I said at github (issue), I've tryied this query it mysql cli and I receive correct answer.
Also, I've tryed to decode url params (with java URLDecoder class). It doesn't helps too.
Thanks, #madhead.
I tryied an advance of #madhead, and it works. So, from this time my DB connection URL looks like this:
val connect = Database.connect(
url = "jdbc:mysql://localhost:3306/my_database_name?characterEncoding=utf8&useUnicode=true",
driver = "com.mysql.jdbc.Driver",
user = user_name,
password = password
)

How to convert objectid to string

I want to get the string character from an ObjectId object. I use pymongo.
eg: ObjectId("543b591d91b9e510a06a42e2"), I want to get "543b591d91b9e510a06a42e2".
I see the doc, It says ObjectId.toString(), ObjectId.valueOf().
So I make this code: from bson.objectid import ObjectId.
But when I use ObjectId.valueOf(), It shows:
'ObjectId' object has no attribute 'valueOf'.
How can I get it? Thanks.
ObjectId.toString() and ObjectId.valueOf() are in Mongo JavaScript API.
In Python API (with PyMongo) proper way is to use pythonic str(object_id) as you suggested in comment, see documentation on ObjectId.
ObjectId.toString() returns the string representation of the ObjectId() object.
In pymongo str(o) get a hex encoded version of ObjectId o.
Check this link.
What works for me is to "sanitize" the output so Pydantic doesn't get indigestion from an _id that is of type ObjectId...here's what works for me...
I'm converting _id to a string before returning the output...
# Get One
#router.get("/{id}")
def get_one(id):
query = {"_id": ObjectId(id)}
resp = db.my_collection.find_one(query)
if resp:
resp['_id'] = str(resp['_id'])
return resp
else:
raise HTTPException(status_code=404, detail=f"Unable to retrieve record")
Use str(ObjectId), as already mentined in the comment by #Simon.
#app.route("/api/employee", methods=['POST'])
def create_employee():
json = request.get_json()
result = employee.insert_employee(json)
return { "id": str(result.inserted_id) }
This is an old thread, but as the existing answers didn't help me:
Having run
new_object = collection.insert_one(doc)
I was able to get the ObjectID with the inserted_id property:
print(f"{new_object.inserted_id}")
In python (Pymongo) there's no inbuilt method to do it so iterate over the result you fetched from db and then typecast _id to str(_id)
result = collection.find({query})
for docs in result:
docs[_id] = str(docs[_id])
first you have to assign the Object Id value to a variable
for example:
let objectId = ObjectId("543b591d91b9e510a06a42e2");
then use the toString method like this
let id = objectId.toString();

NHibernate Criteria Filtering

I use this code to filter database records
if (!string.IsNullOrEmpty(_searchCriteria.MessageType))
{
var messageType = (AutotransferMessageType)Enum.Parse(typeof(AutotransferMessageType), _searchCriteria.MessageType, true);
if (Enum.IsDefined(typeof(AutotransferMessageType), messageType))
{
criteriaQuery.CreateAlias("AutotransferInputRecord", "AutotransferInputRecord")
.Add(
Restrictions.Eq(
"AutotransferInputRecord." + AutotransferLogSearchCriteria.MessageTypePropertyName,
messageType));
}
else
{
criteriaQuery.Add(Restrictions.IsNull("AutotransferInputRecord"));
}
}
AutotransferMessageType is enumerable type
public enum AutotransferMessageType
{
[DisplayName("MT202")]
[DatabaseName("MT202")]
MT202,
[DisplayName("MT210")]
[DatabaseName("MT210")]
MT210,
//...
}
My filter outputs the results when I enter MT202, for example. (It's the right behavior).
When I input just number, for example, 202, I get no results (It's the right behavior too).
But when I try to input some line, "mt", for example, I get error
Unexpected application error has been occured:
'Requested value 'mt' was not found.'
How to make the filter do not show any results when I input a line?
Your error is coming from the line that parses the enum. Use Enum.TryParse instead:
AutotransferMessageType msgEnum;
var enumPrasedOk = Enum.TryParse(_searchCriteria.MessageType, true, out msgEnum);
if(enumPrasedOk){
//Do something
}else{
//Handle case where enum was not found for some reason (if need be)
}
Also please note that you can not look up the enum this way using it's description (in your case they are the same so it is ok).