Error when doing inner join with cross cache join - ignite

I have a studentinfo cache for StudentInfo class and a classinfo cache for ClassInfo,
These two classes are used to do join(Student has an attribute of classId)
With the following code snippet,
SqlFieldsQuery innerJoinSQL = new SqlFieldsQuery(
"select StudentInfo.studentId, StudentInfo.name, StudentInfo.classId from StudentInfo as a, " +
"\"class_cache\".ClassInfo as b where a.classId = b.classId");
cursor = studentCache.query(innerJoinSQL);
for (List data : cursor) {
System.out.println(String.format("studentId %s, studentName %s, classId %s, className %s", data.get(0), data.get(1), data.get(2), data.get(3)));
}
I got following exception:
Exception in thread "main" javax.cache.CacheException: Failed to parse query: select a.studentId, a.name, a.classId, b.name from StudentInfo a, 'class_cache'.ClassInfo b on a.classId = b.classId
at org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.queryTwoStep(IgniteH2Indexing.java:1137)
at org.apache.ignite.internal.processors.query.GridQueryProcessor$2.applyx(GridQueryProcessor.java:732)
at org.apache.ignite.internal.processors.query.GridQueryProcessor$2.applyx(GridQueryProcessor.java:730)
at org.apache.ignite.internal.util.lang.IgniteOutClosureX.apply(IgniteOutClosureX.java:36)
at org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:1666)
at org.apache.ignite.internal.processors.query.GridQueryProcessor.queryTwoStep(GridQueryProcessor.java:730)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxy.query(IgniteCacheProxy.java:700)
at ignite.sqlgrid.join.IgniteSQLJoinQueryTest.main(IgniteSQLJoinQueryTest.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:88)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:613)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "SELECT A.STUDENTID, A.NAME, A.CLASSID, B.NAME FROM STUDENTINFO A, 'class_cache'[*].CLASSINFO B ON A.CLASSID = B.CLASSID "; expected "identifier"; SQL statement:
select a.studentId, a.name, a.classId, b.name from StudentInfo a, 'class_cache'.ClassInfo b on a.classId = b.classId [42001-191]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.getSyntaxError(DbException.java:205)
at org.h2.command.Parser.readIdentifierWithSchema(Parser.java:3115)
at org.h2.command.Parser.readTableFilter(Parser.java:1202)
at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:1884)
at org.h2.command.Parser.parseSelectSimple(Parser.java:2032)
at org.h2.command.Parser.parseSelectSub(Parser.java:1878)
at org.h2.command.Parser.parseSelectUnion(Parser.java:1699)
at org.h2.command.Parser.parseSelect(Parser.java:1687)
at org.h2.command.Parser.parsePrepared(Parser.java:443)
at org.h2.command.Parser.parse(Parser.java:315)
at org.h2.command.Parser.parse(Parser.java:287)
at org.h2.command.Parser.prepareCommand(Parser.java:252)
at org.h2.engine.Session.prepareLocal(Session.java:560)
at org.h2.engine.Session.prepareCommand(Session.java:501)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1188)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:73)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:276)
at org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.prepareStatement(IgniteH2Indexing.java:406)
at org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.queryTwoStep(IgniteH2Indexing.java:1121)
... 12 more
Can some help where the problem is? Thanks!

Looks I figured out the problem.
My two pojo(StudentInfo and ClassInfo) for each cache has one same column named classId. Looks only one pojo can set index = true with annotation #QuerySqlField(index = true) on the classId field
But I am not sure that Ingite has such constraint. If someone knows, let confirm, thanks!

Related

Does JPA criteria api have a problem with JOIN and IN?

This is a JPA Query question. I have successfully used "LEFT JOIN" and "IN:" in EntityManager.CreateQuery in separate situations, but when i combine the two e.g.
SELECT a.id
FROM TableA a
LEFT JOIN TableB b on a.myAField = b.id and b.myBField in :Ids
LEFT JOIN TableC c on b.myBOtherField = c.id
where Ids is List<Long> it starts giving me this error "The left parenthesis is missing from the IN expression."
The sql works fine when pasted directly into postGres pgAdmin explicitly writing out the parameters. Have I made a mistake with the syntax here or is this a jpa limitation and i need an alternative?
List<Long> myBFieldTypes = new ArrayList<>();
myBFieldTypes.add(5L);
myBFieldTypes.add(10L);
try {
List<Long> resultArray = em.createQuery("SELECT a.id FROM TableA a LEFT JOIN TableB b on a.myAField = b.id and b.myBField in :Ids LEFT JOIN TableC c on b.myBOtherField = c.id")
.setParameter("Ids", myBFieldTypes)
.getResultList();
return resultArray;
} catch (Exception ex) {
throw ex;
} finally {
em.close();
}

Hibernate SQL query matching more than one members of an ElementCollection

I have Pojo mapped with JPA annotations like this
#Entity
#Table(name = "record")
public class SearchRecord {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private int id;
private String vidName;
#ElementCollection
private List<String> videoLabels = new ArrayList<String>();
and would like to run a Hibernate query that filters out all SearchRecords that match/contain 1..n videoLabels. (only objects that match all of the videoLabels)
I was able to search for SearchRecords that match a single label by running the following query:
String labelCar = "Car";
String labelPerson = "Person";
TypedQuery<SearchRecord> query = em.createQuery("SELECT b FROM SearchRecord b JOIN b.videoLabels l WHERE l = :param1",SearchRecord.class);
query.setParameter("param1", labelCar);
List<SearchRecord> results = query.getResultList();
But how can I execute a query filtering out all SearchResults matching Car and Person?
Thanks for your support
I was able to solve the problem with the following query
SELECT DISTINCT a FROM SearchRecord a JOIN a.labels b JOIN a.labels c WHERE b.name = 'Car' and c.name = 'Person'

Joining multiple tables using JPA #SecondaryTables

I need to join 3 tables where A.id == B.id and B.id == C.id using JPA #SecondaryTables where I need to map these tables to a single entity. what is the way I should I should try?
Since A.ID = B.ID = C.ID, you can just have 2 secondary tables, with the relationship A.ID = B.ID, and A.ID = C.ID. Your "main" table will be A, and B and C are your secondary tables. You can reference the table as follows in your column declaration. (many other parameters in the annotations left out for brevity)
#Entity
#Table(name = "A")
#SecondaryTables({
#SecondaryTable(name="B", #PrimaryKeyJoinColumn(name="ID", referencedColumnName="ID")),
#SecondaryTable(name="C", #PrimaryKeyJoinColumn(name="ID", referencedColumnName="ID"))
})
public Claass Blah {
#ID
private int id;
#Column(table = "B")
private String someColumn;
#Column(table = "C")
private String someOtherColumn;
etc...
}

JPA forming query which fails at program running

I am doing the following query in JPA:
#NamedQuery(name = PlayerSkill.DELETE_ALL_BOT_DATA,
query = "DELETE FROM PlayerSkill s WHERE s.player.id " +
"IN (SELECT p.id FROM Player p WHERE p.team.id " +
"IN (SELECT t.id FROM Manager m JOIN m.teamInfo t WHERE m.localUserId IS NULL))")
And receiving the following exception when calling appropriate DAO function, which is calling the JPA named query using executeUpdate:
7818 [Thread-12] WARN o.h.e.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 42601
7818 [Thread-12] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - ERROR: syntax error at or near "cross"
Position: 30
7828 [Thread-12] ERROR c.m.s.threads.ServerInitializer - null
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute statement
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387) ~[AbstractEntityManagerImpl.class:4.2.8.Final]
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310) ~[AbstractEntityManagerImpl.class:4.2.8.Final]
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1397) ~[AbstractEntityManagerImpl.class:4.2.8.Final]
at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:111) ~[AbstractQueryImpl.class:4.2.8.Final]
at com.magnifi.pennantrace.dao.player.PlayerSkillDAO.deleteBotTeamsData(PlayerSkillDAO.java:25) ~[PlayerSkillDAO.class:na]
at com.magnifi.schedserv.seasonstartend.SeasonGeneration.deleteAllBotRelatedData(SeasonGeneration.java:1457) ~[SeasonGeneration.class:na]
at com.magnifi.schedserv.seasonstartend.SeasonGeneration.generateSeason(SeasonGeneration.java:109) ~[SeasonGeneration.class:na]
at com.magnifi.schedserv.threads.ServerInitializer.generateEndStart(ServerInitializer.java:161) [ServerInitializer.class:na]
at com.magnifi.schedserv.threads.ServerInitializer.initSystem(ServerInitializer.java:80) [ServerInitializer.class:na]
at com.magnifi.schedserv.threads.SchedulerThread.run(SchedulerThread.java:38) [SchedulerThread.class:na]
Caused by: org.hibernate.exception.SQLGrammarException: could not execute statement
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:123) ~[SQLStateConversionDelegate.class:4.2.8.Final]
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) ~[StandardSQLExceptionConverter.class:4.2.8.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125) ~[SqlExceptionHelper.class:4.2.8.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110) ~[SqlExceptionHelper.class:4.2.8.Final]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:189) ~[ResultSetReturnImpl.class:4.2.8.Final]
at org.hibernate.hql.internal.ast.exec.BasicExecutor.doExecute(BasicExecutor.java:108) ~[BasicExecutor.class:4.2.8.Final]
at org.hibernate.hql.internal.ast.exec.BasicExecutor.execute(BasicExecutor.java:77) ~[BasicExecutor.class:4.2.8.Final]
at org.hibernate.hql.internal.ast.exec.DeleteExecutor.execute(DeleteExecutor.java:124) ~[DeleteExecutor.class:4.2.8.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:415) ~[QueryTranslatorImpl.class:4.2.8.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:282) ~[HQLQueryPlan.class:4.2.8.Final]
at org.hibernate.internal.SessionImpl.executeUpdate(SessionImpl.java:1215) ~[SessionImpl.class:4.2.8.Final]
at org.hibernate.internal.QueryImpl.executeUpdate(QueryImpl.java:116) ~[QueryImpl.class:4.2.8.Final]
at org.hibernate.ejb.QueryImpl.internalExecuteUpdate(QueryImpl.java:198) ~[QueryImpl.class:4.2.8.Final]
at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:102) ~[AbstractQueryImpl.class:4.2.8.Final]
... 6 common frames omitted
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "cross"
Position: 30
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2161) ~[postgresql-9.3-1101.jdbc4.jar:na]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1890) ~[postgresql-9.3-1101.jdbc4.jar:na]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255) ~[postgresql-9.3-1101.jdbc4.jar:na]
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:559) ~[postgresql-9.3-1101.jdbc4.jar:na]
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417) ~[postgresql-9.3-1101.jdbc4.jar:na]
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:363) ~[postgresql-9.3-1101.jdbc4.jar:na]
at org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:100) ~[tomcat-dbcp.jar:8.0.3]
at org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:100) ~[tomcat-dbcp.jar:8.0.3]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:186) ~[ResultSetReturnImpl.class:4.2.8.Final]
... 15 common frames omitted
7832 [Thread-12] ERROR c.m.s.threads.SchedulerThread - null
javax.persistence.RollbackException: Transaction marked as rollbackOnly
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:72) ~[TransactionImpl.class:4.2.8.Final]
at com.magnifi.schedserv.threads.SchedulerThread.run(SchedulerThread.java:39) ~[SchedulerThread.class:na]
The real sql query on that exception is:
delete from bb_player_skills cross join bb_players player1_ where id in (select player2_.id from bb_players player2_ where player2_.team_id in (select teaminfo4_.id from bb_manager manager3_ inner join bb_team_info teaminfo4_ on manager3_.bb_team_info_id=teaminfo4_.id where manager3_.local_user_id is null))
I can't understand why its forming the query using "cross" as it says in the error log.
For a different table the same query works well:
#NamedQuery(name=PlayerStat.DELETE_BOT_DATA,
query = "DELETE FROM PlayerStat s WHERE s.player.id " +
"IN (SELECT p.id FROM Player p WHERE p.team.id " +
"IN (SELECT t.id FROM Manager m JOIN m.teamInfo t WHERE m.localUserId IS NULL))")
And real sql formed by this query is not containing "cross":
delete from bb_player_stat where bb_players_id in (select player1_.id from bb_players player1_ where player1_.team_id in (select teaminfo3_.id from bb_manager manager2_ inner join bb_team_info teaminfo3_ on manager2_.bb_team_info_id=teaminfo3_.id where manager2_.local_user_id is null))
The relation of tables is same also: player skill is one to one to players , same as player stat
EDIT:
for player skills (the one where cross is used) the entity:
#JSON(include=false)
private Player player;
#Id
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name="bb_players_id", nullable=false)
public Player getPlayer() {
return this.player;
}
And for PlayerStat:
private Player player;
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name="bb_players_id", nullable=false)
public Player getPlayer() {
return this.player;
}
In the Player entity:
#OneToOne(mappedBy="player", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
public PlayerSkill getPlayerSkill() {
return this.playerSkill;
}
#OneToOne(mappedBy="player", cascade=CascadeType.ALL)
public PlayerStat getPlayerStats() {
return this.playerStats;
}

LINQ doesn't work with a "select isnull" query..? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Equivalent of SQL ISNULL in LINQ?
Using IsNull or select COALESCE in Linq..?
I've tried this query in LINQ:
string query = #"SELECT ISNULL(P.firstname, s.firstname) AS Expr1,ISNULL(P.lastname,
s.lastname) AS Expr2 FROM comment AS C LEFT OUTER JOIN professor AS P ON P.ID =
C.PID LEFT OUTER JOIN student AS s ON s.ID = C.SID
WHERE (C.VID = 2)";
ArrayList allNames=null;
using (var context = new NewsReaderEntities())
{
ObjectQuery<string> results = context.CreateQuery<string>(query);
// ObjectQuery<string> results1 = context.CreateQuery<string>
(query1,parameters);
foreach (string result in results )
{
allNames.Add(result);
}
}
return allNames;
}
but it returns the error:
linq 'ISNULL' cannot be resolved into a valid type or function. Near
simple identifier,
I've also tried this query:
SELECT COALESCE(p.firstname, s.firstname), COALESCE(p.lastname, s.lastname)
FROM comment c
LEFT JOIN Professor p
ON c.pid = p.id
LEFT JOIN Student s
ON c.sid = s.id
WHERE c.vid = 2
This also raises an error.
Both work okay in SQL Management. Any ideas?
See this example:
var query = from p in Pets select p;
if (OwnerID != null) query = query.Where(x => x.OwnerID == OwnerID);
if (AnotherID != null) query = query.Where(x => x.AnotherID == AnotherID);
if (TypeID != null) query = query.Where(x => x.TypeID == TypeID);
Hope this help you