hibernate query for Getting json key value pair with joins - mysql

I am using REST , hibernate query language for getting some data from database with the help of joins in that query i need to fetch columns from two or more tables and i am getting the result record , and when i return that object through REST as json i am getting the json as in the follwoing format
{"table1col1value","table2col1value","table3colvalue","table1col2value","table2col2value"}
but i need to get the json data in the following format
{"table1colname1":"table1col1value","table2colname":"table2col1value","table1colname":"table3colvalue","table1colname":"table1col2value","table2colname":"table2col2value"}
for that i am using the following code and its working fine, but its working with sql query only i need it in HQL , please help me in this.
#Override
#Transactional
public List<Map<String,Object>> getMixProperties(List<String> keys,Set<String> s) {
StringBuilder sb = new StringBuilder();
sb.append("select ");
Iterator<String> i = keys.iterator();
int q = keys.size();
while (i.hasNext()) {
q=q-1;
if(q==0){
String n= i.next();
sb.append(" "+n);
}
else{
String n2= i.next();
sb.append(" "+n2+",");}
}
sb.append(" from Book Book "
+ " join Systems Systems ON Systems.idSystems =Book.idSystems "
+ " join Machine Machine ON Machine.id =Systems.id ");
/*Iterator<String> iterator = s.iterator();
int q2 = s.size();String s5 = null;
while(iterator.hasNext()) {
String s4 = iterator.next();
q2=q2-1;
if(q2==0){
sb.append(" "+s4+" "+s4);
}
else{
s5=s4;
sb.append(" "+s4+" "+s4+",");}
}*/
System.out.println("query "+sb);
String sbb = sb.toString();
Query query=sessionFactory.getCurrentSession().createSQLQuery(sbb);
query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
List<Map<String,Object>> aliasToValueMapList=query.list();
return aliasToValueMapList;
}
in this above code List keys will be the column name of different tables and (set s will be table names, but i am not using it in current code)
even this is working only if i have both class and db table name are same and property and column names are same, if its not same then its not working.
I am getting JSON only if i have the pojo class , but in my case result set can be any number of columns so its depends on runtime only , please help me in this

Related

How can I detect an access DB table with no columns?

I have a support tool I have written that allows me to create a table in MS Access DB file. Because of the support, I set it so it just creates the table without any columns defined. There is another part of the same program which allows column creations. However when I select the table in my list, I try to load the table. Since the table is empty, the system throws an error at the Fill (I understand the Select is the cause). Is there a way to ask if a table has any columns before trying to load that table?
public static bool ConnectToDatabase(string dbTable)
{
return ConnectToDatabaseWStr(dbTable, "Select * From `" + dbTable + "`");
}
public static bool ConnectToDatabaseWStr(string dbTable, string strSQL)
{
try
{
conn = new OleDbConnection(connectionString);
}
catch (Exception e)
{
LogFile.write(1, "DataAccess: error detected when creating OLEDBConnection.\nConnection string:\n" + connectionString + "\n" + e.ToString() + "\n");
}
try
{
dataAdapter = new OleDbDataAdapter(strSQL, conn);
dataAdapter.Fill(DataSetList[iCurrDataSetListIndex].DataSetInstance, dbTable);
This is easy if there are columns.
You can even go SELECT * from tableName where ID = 0
And then for each the column names. However, while the above will return 0 rows, the columns still do come through. However, without ANY columns, then the above will fail, and you would in theory have to know the "ID" column existed.
You can thus get oleDB provider to return a table as a "schema". This is table of ROWS of the defined table. Thus you can use this:
If NO rows are returned, then we don't have a table that lays out and defines the schema:
var strTableName = "tblHotels";
OleDbConnection myCon = new OleDbConnection(My.Settings.TestDB);
myCon.Open();
string[] SchemaParams = new[] { null, null, strTableName, null };
DataTable MyTable = myCon.GetSchema("Columns", SchemaParams);
if (MyTable.Rows.Count == 0)
// no columns for table
Debug.Print("no columns in table");
else
foreach (DataRow MyRow in MyTable.Rows)
Debug.Print(MyRow("Column_Name") + "->" + MyRow("Data_Type"));

Multiple fields have the same columnName Android Room

I have 3 tables ruser, accounts, accountgroup. Each one has a same column called rsuerId.
I created a POJO class with 3 Embedded objects as below.
class GroupChatItem(
#Embedded
val rUserDto: RUserDto,
#Embedded
val account: AccountDto,
#Embedded
val accountGroup: AccountGroupDto
)
Now, i want to make a query that fetches a GroupChatItem with a given rUserId and accountGroupId like the following.
#Query("""
Select ruser.*, accounts.*, accountgroup.*
from ruser
inner join accounts on accounts.rUserId = ruser.rUserId and accounts.active = 1
inner join accountgroup on accountgroup.rUserId = :rUserId and accountGroup.accountGroupId = :accountGroupId
where ruser.rUserId = :rUserId
""")
suspend fun getGroupChatItem(rUserId: Long, accountGroupId: Int): GroupChatItem
Unfortunately i get the following error.
Multiple fields have the same columnName: rUserId. Field names: rUserDto > rUserId, account > rUserId, accountGroup > rUserId.
I have tried to add a prefix to each embedded object but i get also an error. I dont want to retrieve columns one-by-one because there are many of them.
Is there anything that i missed...??
Thank you
Alternatively you can use the prefix attribute of the Embedded anotation:
class GroupChatItem(
#Embedded(prefix = "user_")
val rUserDto: RUserDto,
#Embedded(prefix = "acc_")
val account: AccountDto,
#Embedded(prefix = "accgr_")
val accountGroup: AccountGroupDto
)
and then alias all the columns of each entity in your SQL query.
I think the prefix attribute is s recent update but I am not sure
I don't believe you have any option other than to have/use :-
a) have distinct columns names across the tables that are to be included in joins (then there is no need to prefix the column names),
or
b) to rename the columns using AS when extracting the values along with a prefix when embedding the entity ensuring that the names match.
I believe that a) would be the simpler option as there is a reduction in the chance of inadvertently using the wrong column name.
As I understand it, the column names have to match for Room to be able to know how to be able to copy a value from the underlying result set, which has no indication of what table a value came from to the value in the returned object or objects.
This is an example of the generated code of a similar scenario 3 embedded entities (User, Office and Places) where some of the column names are the same. They each have and id column and User and Places both have a columns named name.
#Override
public UserOfficePlacesCombined getAllUserOfficePlacesCombined() {
final String _sql = "SELECT user.id AS userid, user.name AS username, office.id AS officeid, office.address AS officeaddress, places.id AS placesid, places.name AS placesname FROM User JOIN Office ON User.id = Office.id JOIN Places ON User.id = Places.id";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
__db.assertNotSuspendingTransaction();
final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
try {
final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "userid");
final int _cursorIndexOfName = CursorUtil.getColumnIndexOrThrow(_cursor, "username");
final int _cursorIndexOfId_1 = CursorUtil.getColumnIndexOrThrow(_cursor, "officeid");
final int _cursorIndexOfAddress = CursorUtil.getColumnIndexOrThrow(_cursor, "officeaddress");
final int _cursorIndexOfId_2 = CursorUtil.getColumnIndexOrThrow(_cursor, "placesid");
final int _cursorIndexOfName_1 = CursorUtil.getColumnIndexOrThrow(_cursor, "placesname");
final UserOfficePlacesCombined _result;
if(_cursor.moveToFirst()) {
final User _tmpUser;
if (! (_cursor.isNull(_cursorIndexOfId) && _cursor.isNull(_cursorIndexOfName))) {
final long _tmpId;
_tmpId = _cursor.getLong(_cursorIndexOfId);
final String _tmpName;
_tmpName = _cursor.getString(_cursorIndexOfName);
_tmpUser = new User(_tmpId,_tmpName);
} else {
_tmpUser = null;
}
final Office _tmpOffice;
if (! (_cursor.isNull(_cursorIndexOfId_1) && _cursor.isNull(_cursorIndexOfAddress))) {
final long _tmpId_1;
_tmpId_1 = _cursor.getLong(_cursorIndexOfId_1);
final String _tmpAddress;
_tmpAddress = _cursor.getString(_cursorIndexOfAddress);
_tmpOffice = new Office(_tmpId_1,_tmpAddress);
} else {
_tmpOffice = null;
}
final Places _tmpPlaces;
if (! (_cursor.isNull(_cursorIndexOfId_2) && _cursor.isNull(_cursorIndexOfName_1))) {
final long _tmpId_2;
_tmpId_2 = _cursor.getLong(_cursorIndexOfId_2);
final String _tmpName_1;
_tmpName_1 = _cursor.getString(_cursorIndexOfName_1);
_tmpPlaces = new Places(_tmpId_2,_tmpName_1);
} else {
_tmpPlaces = null;
}
_result = new UserOfficePlacesCombined();
_result.setUser(_tmpUser);
_result.setOffice(_tmpOffice);
_result.setPlaces(_tmpPlaces);
} else {
_result = null;
}
return _result;
} finally {
_cursor.close();
_statement.release();
}
}
The critical lines are the ones like :-
final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "userid")
This is used to search for the column's names in the Cursor (aka result set) and return the offset to the column, the index then being used to get the actual value from the Cursor.
In your scenario the result set will include some like
rUserId rUserId rUserId*
Which one should it use for which? You may know/understand that first is ruser.rUserId, and that the second is account.rUserId and that the third is accountgroup.rUserId but Room, as it stands, will not know when generating the code. So in all 3 instances when getColumnIndex("rUserId") is used, it will return either 0 (the first) it breaks out of the loop, or 2 if it continues rather than breaks out of the loop (I believe it doesn't break out of the loop).

JPA Aggreate values return type and conversion to json , jax-rs 2.0

In full column selection query like
select e from Entity e
the result type is of Entity and when aggregate functions used in query e.g in my code below
#GET
#Path("/list")
#Produces(MediaType.APPLICATION_JSON)
public Response getAverage() throws JsonGenerationException, JsonMappingException, IOException{
Timestamp startDate =Timestamp.valueOf("2016-11-15 14:12:17");
Timestamp endDate =Timestamp.valueOf("2016-11-21 16:12:17");
EntityManagerFactory emf =Persistence.createEntityManagerFactory("NeoMetrics");
EntityManager em = emf.createEntityManager();
Query q = em.createQuery("Select avg(e.uniqueCalls) , avg(e.primaryCalls) , avg(e.secondaryCalls), "
+ "avg(e.backupCalls), avg(e.uniqueS1Calls),"
+ " avg(e.uniqueS2Calls) as s2calls, avg(e.uniqueS3Calls), avg(e.uniqueS4Calls)"
+ " from ESnapshot e where e.queueid = :id and e.sampleTS between :startDate and :endDate",ESnapshot.class);
q.setParameter("id",2);
q.setParameter("startDate",startDate);
q.setParameter("endDate",endDate);
Object[] es = (Object[]) q.getSingleResult();
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(es);
return Response.ok(json).build();
}
the result is an object array and after changing it to string it become string array using object mapper , here is the output . But what i really need is proper json format with key and values, the column from table as keys . any help will be really appreciated

Load 3D model in Unity using Resource folder and Mysql

I want to load 3D model using Resource folder. I created an sql database to store the address. In this case I stored the file "deer-3ds" in folder "Models" and also save these information in a table named "modeladdress" in sql.
So please help me to correct my code. I know that it's 100% wrong but I dont know how to fix it. Thank you.
using UnityEngine;
using System.Collections;
using System;
using System.Data;
using Mono.Data.Sqlite;
public class addobject : MonoBehaviour {
// Use this for initialization
void Start () {
//GameObject deer=Instantiate(Resources.Load("deer-3d.bak",typeof(GameObject)))as GameObject;
// GameObject instance = Instantiate(Resources.Load("Models/deer-3ds", typeof(GameObject))) as GameObject;
string conn = "URI=file:" + Application.dataPath + "/modeladdress.s3db"; //Path to database.
IDbConnection dbconn;
dbconn = (IDbConnection) new SqliteConnection(conn);
dbconn.Open(); //Open connection to the database.
IDbCommand dbcmd = dbconn.CreateCommand();
string sqlQuery = "SELECT ordinary,foldername, filename " + "FROM modeladdress";
dbcmd.CommandText = sqlQuery;
IDataReader reader = dbcmd.ExecuteReader();
while (reader.Read ()) {
int ordinary = reader.GetInt32 (0);
string foldername = reader.GetString (1);
string filename = reader.GetString (2);
string path = foldername + "/" + filename;
//Debug.Log( "value= "+value+" name ="+name+" random ="+ rand);
GameObject instance = Instantiate(Resources.Load(path, typeof(GameObject))) as GameObject;
instance.SetActive (true);
}
reader.Close();
reader = null;
dbcmd.Dispose();
dbcmd = null;
dbconn.Close();
dbconn = null;
}
// Update is called once per frame
void Update () {
// GameObject instance = Instantiate(Resources.Load("Models/deer-3ds", typeof(GameObject))) as GameObject;
// instance.SetActive (true);
}
}
First of all, you are using SQLite at your database management system, not MySQL. Second, the way you have written your query,
string sqlQuery = "SELECT ordinary,foldername, filename " + "FROM modeladdress";
Will return the ordinary, foldername, and filename for every model. You need to use a WHERE clause to specify precisely which model you want to use. Thus, you need some way to know which model you want to query from the database before you actually execute the query, and in that case, why even query a database? You're going to have to store some unique identifier anyway so a database solves nothing.
Now concerning the actual code you have written, it appears to be correct (i.e. it should be returning what you want). The problem must be that either your table is empty, your values that are returned are incorrect, or that the object is being instantiated in an incorrect location and thus you are thinking it's not working. If you want a more concrete answer you'll have to comment on this answer with the specific problem you are facing (i.e. what specifically is "wrong"?).

How to generate a JSON file from Mondrian output

I am new to Mondrian. I am using it in my project for OLAP operations.
I am testing it with Foodmart database.
The problem is that I need the OLAP operations results in JSON format.
I know that mondrian has the same structure as JSON in the form of hierarchies.
I want to generate a JSON file as an output from the result of mondrian MDX query.
The result should be similar to OLAP operations.
I don't know how to iterate over the result generated from MDX query.
Here is the code.
String connStr = "Provider=mondrian;" +
"Catalog=/WEB-INF/FoodMart.xml;" +
"JdbcDrivers=com.mysql.jdbc.Driver;" +
"Jdbc=jdbc:mysql://localhost/foodmart;" +
"jdbcUser=root;" +
"jdbcPassword=;";
String queryStr ="select {[Measures].[Unit Sales], [Measures].[Store Cost], [Measures].>Store Sales]} ON COLUMNS,"+"Crossjoin(Hierarchize(Union({[Promotion Media].[All Media]}, >[Promotion Media].[All Media].Children)), {[Product].[All Products]})
ON ROWS"+" from [Sales]"+"where [Time].[1997]";
Connection connection = DriverManager.getConnection(connStr, null);
Query query = connection.parseQuery(queryStr);
Result result = connection.execute(query);
result.print(new PrintWriter(System.out));
Actually I need to perform OLAP operations on data warehouse which is stored in MySQL.
The resulted data should be in JSON format which I will pass to D3 http://mbostock.github.com/d3 for visualizations.
For data format I have to use JSON format.
Please any suggestions how to iterate MDX result and convert it in JSON file.
I am using Pentaho Mondrian for this purpose.
Thanks.
if you are working with PHP you could use this library to transform the xmla result into Json
http://www.ibm.com/developerworks/xml/library/x-xml2jsonphp/
Here's an example of what i suppose you want to do:
Class.forName("mondrian.olap4j.MondrianOlap4jDriver"); //load the driver
Connection connection = DriverManager.getConnection("Provider=mondrian;" +
"Catalog=/WEB-INF/FoodMart.xml;" +
"JdbcDrivers=com.mysql.jdbc.Driver;" +
"Jdbc=jdbc:mysql://localhost/foodmart;" +
"jdbcUser=root;" +
"jdbcPassword=;");
OlapWrapper wrapper = (OlapWrapper) connection;
OlapConnection olapConnection = wrapper.unwrap(OlapConnection.class);
CellSet cellSet = statement.executeOlapQuery(query);
CellSetAxis rows = cellSet.getAxes().get(1); //cube rows
CellSetAxis columns = cellSet.getAxes().get(0); //cube columns
int resultSize = rows.getPositionCount() * columns.getPositionCount();
String resultValues[] = new String[resultSize];
int valueIndex = 0;
for (Position row : rows) {
for (Position column : columns) {
Cell cell = cellSet.getCell(column, row);
String cellValue = cell.getFormattedValue();
resultValues[valueIndex++] = cellValue;
}
}
Gson gson = new Gson(); //gson library instance
String resultString = gson.toJson(responseValues); //json string
olapConnection.close();
connection.close();