jooq getValue(String fieldName) Columns with the same name in different tables - java

SQL:
SELECT tblA.hostname, tblB.hostname FROM tblA, tblB ...
When trying to get the hostname from each table, it does not work. For example,
String clientHostname = (String) result.getValue("tblA.hostname");
String serverHostname = (String) result.getValue("tblB.hostname");
Execution exception: [IllegalArgumentException: Field (tblA.hostname) is not contained in Row (hostname, hostname)]
Then, another attempt to correct the issue with:
String clientHostname = (String) result.getValue("hostname");
String serverHostname = (String) result.getValue("hostname");
This does not return the desired behavior where clientHostname = tblA.hostname and serverHostname = tblB.hostname, it just returns tblA.hostname for both.
How do I get the values for both columns?

Have you tried this?
"SELECT tblA.hostname AS tblAhostname, tblB.hostname AS tblBhostname FROM tblA, tblB ..."
String clientHostname = (String) result.getValue("tblAhostname");
String serverHostname = (String) result.getValue("tblBhostname");

Apart from explicitly renaming columns as Erik suggested, you can access qualified column names like this:
String clientHostname = result.getValue(field(name("tblA", "hostname"), String.class));
String serverHostname = result.getValue(field(name("tblB", "hostname"), String.class));
This solution makes use of:
DSL.field(Name, Class) to construct a "plain SQL" field
DSL.name(String...) to construct an identifier
More information about this API can be found in the manual:
http://www.jooq.org/doc/latest/manual/sql-building/plain-sql
Note, there's also a pending feature request #4578 to allow for using the API the way you have intended.

Related

AWS SDK Java DynamoDB - Query with Expression Attribute Name - An expression attribute value used in expression is not defined

Similar to: I cannot query my dynamodb table from aws lambda due to wrong filterexpression? and DynamoDB update error Invalid UpdateExpression: An expression attribute value used in expression is not defined
I am trying to code a way to query DynamoDB tables using partial matches on Partition Key / Sort Key in Java.
The DynamoDB table I am trying to access has a Partition key of "Type" (A restricted key word in DynamoDB, I know, but not my choice) and a Sort key of "Id". I know the "Type" but not the full Id, so I have researched the Query method using AWS SDK 2.x source code and have implemented as shown below:
DynamoDBClient dynamoDbClient = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
.build();
String idKey = "wholeIdKey";
String idValue = "partialIdValue";
String typeValue = "typeValue";
Map<String, String> expressionNames = new HashMap<>();
expressionNames.put("#t", "Type");
QueryRequest request = QueryRequest.builder()
.tableName(tableName)
.keyConditionExpression("begins_with ( " + idKey + ", :" + idValue + " )
AND #t = :" + typeValue)
.expressionAttributeNames(expressionNames)
.build();
QueryResponse response = dynamoDbClient.query(request);
However, when I run this code, I get the following error message:
Exception in thread "main" software.amazon.awssdk.services.dynamodb.model.DynamoDbException:
Invalid KeyConditionExpression: An expression attribute value used in expression is not defined; attribute value: :typeValue
It's as if it's not recognizing the fact that I have told the code use the Expression Attribute Names feature to replace the "#t" with "Type" (Which is a reserved keyword in DynamoDB)
Can anyone help?
EDIT: References for code:
https://docs.aws.amazon.com/code-samples/latest/catalog/javav2-dynamodb-src-main-java-com-example-dynamodb-Query.java.html
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html
https://www.javadoc.io/static/software.amazon.awssdk/dynamodb/2.7.14/software/amazon/awssdk/services/dynamodb/model/QueryRequest.html#expressionAttributeNames--
The name is fine, but you're prefixing both values with ':'. That causes a lookup in ExpressionAttributeValues, which you did not provide.
Never try to write dynamic values directly into the query string.
Your expressionAttributeName looks fine, but you forgot to provide a value for :typeValue so dynamoDB cannot know what to look for.
In addition to what you did, you need to add an expressionAttributeValue where you can provide proper values. See documentation here
Fixed Code for whoever wants it in the future (Thanks to #aherve and #MattTimmermans)
DynamoDBClient dynamoDbClient = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.credentialsProvider(StaticCredentialsProvider.create(awsCredentials))
.build();
String idKey = "wholeIdKey";
String idValue = "partialIdValue";
String typeValue = "typeValue";
String typeKey = "typeKey";
Map<String, String> expressionNames = new HashMap<>();
expressionNames.put("#t", "Type");
expressionNames.put("#i", "Id");
Map<String, AttributeValue> expressionValues = new HashMap<>();
expressionValues.put(":typeName", AttributeValue.builder().s(typeValue).build());
expressionValues.put(":idName", AttributeValue.builder().s(idValue).build());
QueryRequest request = QueryRequest.builder()
.tableName(tableName)
.keyConditionExpression("#t = :typeName AND begins_with ( #i, :idName )")
.expressionAttributeNames(expressionNames)
.expressionAttributeValues(expressionValues)
.build();
response = dynamoDbClient.query(request);

Trouble with getting strings into JSON

My servlet recieves/loads multiple parameters from/for an article (price, id, count, name).
While they are saved in the session for other purposes I want to display them in a Shopping cart.
So my idea was to get all values into a json like this
{"id":1, "prductName":"article1"}
but my json always ends up empty.
I had two approaches:
String prname = request.getParameter("name");
String anz = String.valueOf(session.getAttribute("Anzahl"));
String prid = request.getParameter("id");
String price = request.getParameter("price");
These are my parameters:
First try:
class ToJson{
String prname1 = String.valueOf(session.getAttribute("prname"));
String anz1 = String.valueOf(session.getAttribute("Anzahl"));
String prid1 = String.valueOf(session.getAttribute("id"));
String price1 = String.valueOf(session.getAttribute("price"));
}
ToJson obj = new ToJson();
Jsonb jsonb = JsonbBuilder.create();
String jsn1 = jsonb.toJson(obj);
Ends up with: {}
Second try:
ArrayList<String> ar = new ArrayList<String>();
ar.add(prname);
ar.add(price);
ar.add(prid);
ar.add(anz);
ToJson obj = new ToJson();
Jsonb jsonb = JsonbBuilder.create();
String jsn = jsonb.toJson(ar);
Ends up with: ["P1neu","25","1","145"]
It isn't in a format I wanted and I also don't know how to access the seperate values here, I tried jsn[1] but it didnt work.
Could you help me, please?
To your first question, why JSON object is printing empty:
You are missing getters & setters in the ToJSON class for JSON Builder/Parser to access the properties/fields, and that's why its printing as empty object.
To your second question, how do I access JSON properties:
JSON representation is a natively a string representation, and you can't read part of string as jsn[1].
For reading JSON object properties, you convert it into POJO using available any of preferred open source parser libraries like Jacksons, Gson etc. And then access POJO properties using standard java getter/setters.

How to use Apache Tika to extract the "Subject” field by using Apache Metadata class ?

I'm trying to extract the "Subject" field from an email, but am having some trouble . I was able to get the "To" and "From" fields already, like so :
String messageTo = tikaMetadata.MESSAGE_TO; //Works fine
String toField = tikaMetadata.get(messageTo); //Works fine
System.out.println("From field is : " + fromField); //Works fine
System.out.println("To field is : " + toField); //Works fine
String messageSubj = tikaMetadata.getValues("Message:Raw-Header:Subject");
String subjField = tikaMetadata.get(messageTo); //Doesn't Work
How would we extract the subject field by using Tika ?
any tips helpful thanks
You can try two ways:
String subjectObs = tikaMetadata.get(tikaMetadata.SUBJECT);
but where.SUBJECT is deprecated
String subject = tikaMetadata.get(TikaCoreProperties.DESCRIPTION);probably the substitute that is closest to Metadata.SUBJECT (for more details about TikaCoreProperties look at this: tika documentation)

How to handle foreign addresses in Java application that calls Nominatim Webservice

The following code produces a string that has question marks as the display name when I insert an Iranian address(?????, ???????). However if I put the same url into my browser, it returns Tehran, Iran instead of question marks. I know that it has something to do with encoding but how do I get the English text as the browser returns in my java application?
String rawAddress = "Tehran";
String address = URLEncoder.encode(rawAddress, "utf-8");
String geocodeURL = "http://nominatim.openstreetmap.org/search?format=json&limit=1&polygon=0&addressdetails=0&email=myemail#gmail.com&languagecodes=en&q=";
String formattedUrl = geocodeURL + address;
URL theGeocodeUrl = new URL(formattedUrl);
System.out.println("HERE " +theGeocodeUrl.toString());
InputStream is = theGeocodeUrl.openStream();
final ObjectMapper mapper = new ObjectMapper();
final List<Object> dealData = mapper.readValue(is, List.class);
System.out.println(dealData.get(0).toString());
I tried the following code but it produced this: تهران, �ايران‎ for the display name which should be Tehran, Iran.
System.out.println(new String(dealData.get(0).toString().getBytes("UTF-8")));
Use "accept-language" in the URL parameter for Nominatim to specify the preferred language of Nominatim's results, overriding whatever default the HTTP header may set. From the documentation:
accept-language= <browser language string>
Preferred language order for showing search results, overrides the
value specified in the "Accept-Language" HTTP header. Either uses
standard rfc2616 accept-language string or a simple comma separated
list of language codes.

How to get values of getParameterValues in the order they are sent?

I am sending registration form data through HttpPost method to Servlet and get this data by getParameterValues.
No problem with getting data, but I get the data in random order. I want that at servlet I get the data in order of how they are sent. I try to solve this by reading in internet but nothing can help. I am posting my servlet code here.
response.setContentType("text/html");
ObjectOutputStream out = new ObjectOutputStream(response.getOutputStream());
Enumeration paramNames = request.getParameterNames();
String params[] = new String[7];
int i=0;
while(paramNames.hasMoreElements())
{
String paramName = (String) paramNames.nextElement();
System.out.println(paramName);
String[] paramValues = request.getParameterValues(paramName);
params[i] = paramValues[0];
System.out.println(params[i]);
i++;
}
I get the output like this
5_Country
United States
4_Password
zxcbbnm
1_Lastname
xyz
0_Firstname
abc
3_Email
abc#xyz.com
6_Mobile
1471471471
2_Username
abcd
I want 0_Firstname first then 1_Lastname then 2_Username like that, because I want to insert this data in database. Here 0,1,2...I wrote just for indicate that I want value in this order.
Try this
Enumeration<String> enumParamNames = request.getParameterNames();
Convert Enumeration to List inorder to sort them.
List<String> listParamNames = Collections.list(enumParamNames);
The paramNames will look like this before sorting
[5_Country, 4_Password, 1_Lastname, 0_Firstname, 2_Username, 3_Email]
Sort the list by Collections.sort(listParamNames);
The sorted paramNames will look like this
[0_Firstname, 1_Lastname, 2_Username, 3_Email, 4_Password, 5_Country]
Now you can loop with listParamNames to get the associated param value
for(String paramName : listParamNames)
{
System.out.println(paramName);
System.out.print("\t");
/* Instead of using getParameterValues() which will get you String array, in your case no need for that. You need only one `Value`, so you go with `getParameter` */
System.out.print(request.getParameter(paramName));
}
Output:
0_Firstname - abc
1_Lastname - xyz
etc....
You won't get the parameter names in order by using request.getParameterNames(); .
You can either use
String [] parameterNames = new String[]{"param1","param2","param3"};
for(String param : parameterNames){
System.out.println(param);
}
where parameterNames conains sequence in which you want your parameters.
You can even configure it and read sequence from a config file.
OR
You can use
request.getQueryString() to get the QueryString, while using GET Method
OR
You can use
request.getInputStream() to get the QueryString, while using POST Method
and parse the raw data to get the Query string.
After getting query string , you can split and use the way you want.

Categories