JPQL query to join multiple tables - jpql

i am quite new to JPQL, i have 3 entity class Book,Loan,member, relationship
Loan-Book(#OneToOne)unidirection
Loan-Member(#OneToMany)unidirectional
snippet from my loan class
public class loan implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String dateofissue;
private String dueDate;
#OneToOne
#JoinColumn(name = "bookid")
private book Bookid;
#ManyToOne
#JoinColumn(name="member_ID")
private member memberid;
when i write a very simple query "Select Loan from loan loan"; i get all the columns including columns member and books because of the relation
how can i write a JPQL query to return selected column book.title,book.id,loan.duedate,member.firstname,member.id from book,loan,member
the purpose of the query is to retrive all the borrowed books, by all member
thank you

You already have mappings define so just directly reference them in JPQL.
select l.Bookid.title, l.Bookid.id, loan.duedate, l.memberid.firstname,
l.memberid.id from loan l;
or you can create aliases also for shorter name.
select book.title, book.id, loan.duedate, member.firstname, member.id
from loan l join l.Book book join l.Member member;

Related

Get OrmLite database column name from property name

Let's say I have this class:
public class FooBar
{
public long Id {get; set;}
public string BarFoo {get; set;}
}
OrmLite when using postgresql will create table name foo_bar and columns id, and bar_foo.
I can get the table name for use in a custom query like so:
db.ExecuteSql($"INSERT INTO {db.GetTableName<SomeOtherClass>()}(bar_foo) SELECT bar_foo FROM {db.GetTableName<FooBar>()}");
If the naming convention changes or the property is re-named then the query breaks because the column bar_foo is defined as a string.
How do I define the column names in the same fashion I am defining the table names?
You can get the table & column names from the dialect provider, e.g:
var dialect = db.Dialect(); //older API db.GetDialectProvider()
By their name where it will use the configured NamingStrategy:
var tableName = dialect.GetQuotedTableName(nameof(FooBar));
var columnName = dialect.GetQuotedColumnName(nameof(FooBar.BarFoo));
By OrmLite's model & field definition where it will also make use of any RDBMS [Alias] customizations defined on the model:
var modelDef = typeof(FooBar).GetModelMetadata();
var fieldDef = modelDef.GetFieldDefinition(nameof(FooBar.BarFoo));
var tableName = dialect.GetQuotedTableName(modelDef);
var columnName = dialect.GetQuotedColumnName(modelDef,fieldDef);

Cassandra CQL where clause parentheses

Having this Entity
#Table(keyspace = KEYSPACE)
public class CE_TimeSeries extends Entity implements TimeSeriesPoint{
#PartitionKey(1)
private String typeId;
#ClusteringColumn(value=1, asc=true)
private String userId;
#ClusteringColumn(value=2, asc=true)
private Date startDate;
#Column
private Date endDate;
#Column
private int groupInterval;
#Column
private int interval;
}
This CQL
SELECT startDate, endDate, groupInterval, interval FROM CE_TimeSeries WHERE typeId
= :typeId and userId = :userId and ( endDate >= :fromDate or ( startDate >=
:fromDate and startDate <= :toDate ) )
Give the Exception :
Caused by: com.datastax.driver.core.exceptions.SyntaxError: line 1:142
mismatched input 'or' expecting ')' (... ( endDate >= :fromDate [or] (...)
While I don't actually see a question here, I'll assume that you are wondering why you are getting an exception. There are two things wrong with your query.
CQL does not allow the use of OR in the WHERE clause.
CQL does not allow parens in the WHERE clause. Plus, not having OR available kind of precludes the need for parens.
The bottom line, is that CQL is not SQL, and the logic you can apply in the WHERE clause is largely dependent on the storage model.

azure table storage partitionkey/row key background?

I'm reviewing Azure tables in an existing implementation. Here's an example of data from 1 row:
partitionkey (string):
6b348096-e6cb-4126-ba3c-cd0c9e8ba9c9
rowkey (string):
02519452888782521547_c1a98e0f-1b25-4d38-bd96-d72b30a97bf0
Obviously, rowkey does not have a proper guid and both column names are native to Azure and required per entity. There does not appear to be an identity or default insert for these columns. Can someone please provide context around these columns and the implementation style differences and considerations between these Azure columns vs a SQL Server style implementation?
I have no idea about how the partition key and row key are constructed in your table, please turn to someone who created the table. :)
About the considerations on the Azure Table design, you can refer to this post (which is very complete and helpful).
Partitionkey and Rowkey are just two properties of entitis in Azure table. Rowkey is the "primary key" within one partition. Within one PartitionKey, you can only have unique RowKeys. If you use multiple partitions, the same RowKey can be reused in every partition. PartitionKey + RowKey form the unique identifier(Primary key) for an entity.
In your table, the partitionkey and rowkey are just assigned with a random string. I'm not sure whether you designed this table or somebody else, but these two properties can be assigned with other values through Azure Storage .NET client libary and Rest API. As the example below, you can design the rowkey and partitionkey, and assign whatever valid value you want, here lastname for Partitionkey and firstname for rowkey:
public class CustomerEntity : TableEntity
{
public CustomerEntity(string lastName, string firstName)
{
this.PartitionKey = lastName;
this.RowKey = firstName;
}
public CustomerEntity() { }
public string Email { get; set; }
public string PhoneNumber { get; set; }
}
It’s better to think about both properties and your partitioning strategy. Don’t just assign them a guid or a random string as it does matter for performance. I recommend you go through Designing a Scalable Partitioning Strategy for Azure Table Storage, the most commom used is Range Partitions, but you can choose whatever you want.
This is a great blog help you understand how partitionkey and rowkey work http://blog.maartenballiauw.be/post/2012/10/08/What-PartitionKey-and-RowKey-are-for-in-Windows-Azure-Table-Storage.aspx

Astyanax getKey with compound key

I would like to run the following code with a compound primary key.
Column<String> result = keyspace.prepareQuery(CF_COUNTER1)
.getKey(rowKey)
.getColumn("Column1")
.execute().getResult();
Long counterValue = result.getLongValue();
Research seems to show that it can be a string that represents a key (if it's not a compound primary key). The documentation says that it is of type K, alas, I am not very experience with Java, and have no idea what that means. Is it just a base type that lots of stuff inherits from? If so, I'm not really any closer to knowing what getKey(K) needs in order to handle a compound key (am I?).
You just need to write a class that fits the columns in your data model. You can then give this class to Astyanax in your mutations or queries.
For example, if you had a data model like this
CREATE TABLE fishblogs (
userid varchar,
when timestamp,
fishtype varchar,
blog varchar,
image blob,
PRIMARY KEY (userid, when, fishtype)
);
you would create a class like this:
public class FishBlog {
#Component(ordinal = 0)
public long when;
#Component(ordinal = 1)
public String fishtype;
#Component(ordinal = 2)
public String field;
public FishBlog() {
}
}
When and fishtype form your composite column key and are represented by the FishBlog class. Userid would be your row/partition key and can be of the simple "string" type.
Have a look at this blog explaining in great detail how to insert data with composite keys (where I took this example from).
Hope that helps.

JPQL BETWEEN Date Interval

I tried to get all MainIntervals in a certain date interval. But I get always null.
Here is the JPA Entity
#Table(name="MAIN_INTERVAL")
#NamedQueries({
#NamedQuery(name = MainInterval.FIND_ALL, query = " select m from MainInterval m"),
#NamedQuery(name = MainInterval.FIND_BETWEEN,
query = "select m from MainInterval m where m.mainIntervalStart
BETWEEN :startDate AND :endDate
AND m.mainIntervalEnd BETWEEN :startDate AND :endDate"
) })
public class MainInterval implements Serializable {
public static final String FIND_ALL = "MainInterval.findAll";
public static final String FIND_BETWEEN = "MainInterval.findBetween";
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="MAIN_INTERVAL_ID")
private Long id;
#Column(name="MAIN_INTERVAL_START")
#Temporal(javax.persistence.TemporalType.DATE)
private Date mainIntervalStart;
#Column(name="MAIN_INTERVAL_END")
#Temporal(javax.persistence.TemporalType.DATE)
private Date mainIntervalEnd; }
And in the EJB SessionBeans I have the method:
public List<MainInterval> findMainIntervalsBetween(Date startDate, Date endDate){
List<MainInterval> resultList = em.createNamedQuery(MainInterval.FIND_BETWEEN, MainInterval.class)
.setParameter("startDate", startDate, TemporalType.DATE).setParameter("endDate", endDate, TemporalType.DATE).getResultList();
return resultList;
}
But when I call it from JSF with CDI the resultList is always null. Although I have some MainIntervals that meet the conditions between startDate and endDate.
I would be very grateful to every answer or links for tutorial.
Best regards!
Your query is:
select m from MainInterval m where m.mainIntervalStart
BETWEEN :startDate AND :endDate
AND m.mainIntervalEnd BETWEEN :startDate AND :endDate
Your first row's interval is [01.05.2012, 31.05.2012], and your second row's interval is [01.05.2012, 01.08.2012]. The arguments of the query are 10.05.2012, 20.05.2012.
So, for your first row:
m.mainIntervalStart BETWEEN :startDate AND :endDate
01.05.2012 BETWEEN 10.05.2012 AND 20.05.2012 : false
So the first row is not returned.
For your second row:
m.mainIntervalStart BETWEEN :startDate AND :endDate
01.05.2012 BETWEEN 10.05.2012 AND 20.05.2012 : false
So the second row isn't returned either.
Everything looks normal to me.

Resources