Let'say i have the following tables:
Table A: id b-id
Table B: id property
Can I filter elements of table A like the following in JPQL language?
SELECT a FROM A a JOIN a.b-id targetId WHERE targetId.property = : someValue
I'd like to get table A's elements in which the referenced B element has property = someValue
And if I introduce a third table
Table A: id b-id
Table B: id c-id
Table C: id property
How can I get A's elements where c.property=someValue ?
I'm starting to get a sense of the power of ORM but some concepts are still vague to me.
Thank you for your answer
JPQL queries operate to entities, not to database tables. I assume names of entities and persistent attributes match to the names of tables and database columns given in question.
Because all relations in question are single valued, one-to-one or many-to-one (each A is connected only to one B (or possibly not to any), each B is connected to one C), specifying joins in query is not needed at all.
SELECT a FROM A a WHERE a.b.c.property = someValue
There is no need to worry about null values in path, because as said in JPA 2.0 specification:
Path expression navigability is composed using “inner join” semantics.
That is, if the value of a non-terminal field in the path expression is null,
the path is considered to have no value, and does not participate in the
determination of the result.
Same does not work for collection valued attributes (one-to-many, many-to-many), because it is not possible to navigate to their attributes via path expressions.
Related
I mainly focus on the query operation, not union or intersection.
Here is an example.
Let say we have a multi-level category:
CATEGORY-TOP-LEVEL:
CATEGORY1:
CATEGORY1.1:
item1
CATEGORY2:
CATEGORY2.1:
item2
Here, item[N] is the data. Category is a tree structure to represent which category the item belongs to.
Now, suppose I'd like to query all data in category 1, the database should give me item1.
Suppose I'd like to query all data in category-top-level, the database should give me item1 and item2.
It's like set theory. Because item1 belongs to CATEGORY1.1, and CATEGORY1.1 belongs to CATEGORY1. Thus item1 belongs to CATEGORY1.
One solution is use Materialized Paths: We put an field in item, named path, the value is like: ",CATEGORY-TOP-LEVEL,CATEGORY1,CATEGORY1.2". But the problem is it will cause a lot of writing operations when I change a category's name or the hierarchy of the category.
Can MongoDB support that? if not, is there a database can support that?
P.S. Let's take query performance into consideration.
Every modern relational database can support that.
There are different ways of modeling this in a relational database, the most common one is called the "adjacency model":
create table category
(
id integer primary key,
name varchar(100) not null,
parent_category_id integer references category
);
If an item can only ever belong to a single category, the item table would look like this:
create table item
(
id integer primary key,
name varchar(100) not null,
category_id integer not null rerences category
);
If an item can belong to more then one category, you need a many-to-many relationship (also very common in the relational world)
To get all categories below a certain category you can use a recursive query:
with recursive cat_tree as (
select id, name, parent_category_id
from category
where id = 42 -- this is the category where you want to start
union all
select c.id, c.name, c.parent_category_id
from category c
join cat_tree p on p.id = c.parent_category_id
)
select *
from cat_tree;
To get the items together with the categories, just join the above to the item table.
The above query is standard ANSI SQL.
Other popular models are the nested set model, the materialized path (you mentioned that) and the closure table.
This gets asked a lot. See the tags recursive-query and hierarchical-data for many more examples.
I have one row in my PostgreSQL table with the name I look for, but Ebean query gives me two identic results (same primary key). Each row has a unique name so I must be able to findUnique()
finder.where().eq("name", name).findUnique()
Handmade sql query gives me only one
String sql = "select id, name from totem where name ilike :name";
Any idea to get findUnique() working ?
Is it an Ebean bug ?
I have a OnetoOne relationship with table B.
So Ebean generates an inner join with this table.
Table B has two entry corresponding the object I'm fetching on table A.
So the request returns 2 rows.
I have an EF 4 data model with TPT mapping.
I have a strange behaviour about the generated SQL of a query .
Lets say entity A is a base entity , A has two derived entities B and C , also A has many associations with other entities (say E,D).
When I make a simple select on A , Context.A.First() , I profiled the generated SQL from this entity and it has all the joins with the other entities.
Do you have a ny suggestion why this happen ? fixes ? any tip.
Thanks in advance ...
Context.A is the set of all A entities - including all B and C entities because every B and C is an A. It is not the set of all A entities that are not a B or C.
Therefore, if you request the first A in the database by Context.A.First() it could be a B or C or just an A. To find the concrete type of that first A the only way with TPT inheritance is to check if there are related records in the B or C table that have the same primary key like the first record in the A table. If there are related records this A is of type B (or C) and all column values from the record in table B (or C) have to be loaded together with the column values from the base record in table A in order to materialize an entity object of the correct type B (or C). If there are no related records in table B or C the concrete type is just an A.
In any case a join to the related B or C tables is required to figure out if there is a record or not and to determine the concrete type of the first A.
So, the joins you are seeing are expected behaviour when you use TPT inheritance and you can't avoid them. It has a negative impact on performance, yes, which is the biggest downside of TPT modeling.
I'm new to PostgreSQL.
I was wondering, how do I make a column a drop down list.
So i've got a table called Student. There's a column in there called "student_type", which means whether the student is a part time student, full time student or is sandwich course student.
So I want to make "student_type" a drop down list with 3 choices: "part time" student, "full time" and "sandwich".
How do I do this?
(I'm using pgAdmin to create the databse, by the way.)
A drop-down is a client side thing and should be dealt with accordingly. But as far as a relational database is involved there should exist a student_type relation with the id and type columns which you would query like this:
select st.id, st.type
from student_type st
inner join student s on s.type_id = st.id
group by st.id, st.type
order by st.type
The inner join is to make sure you don't show an option that does not exist in the student table and would therefore produce an empty result if chosen. In the client side the id should be the option value and the type the option text.
If there is no student_type relation as a consequence of bad db design or if you are only allowed to query a denormalized view, you can still use the student relation:
select distinct student_type
from student
order by student_type
In this case the student_type will be both the option value and the option text.
I think You use MS Access before. It is not possible to create such a drop-down list using pgAdmin, but it is possible to limit acceptable values in field "student_type" in a few different ways. Still, this will not be a drop-down or Combobox filed.
eg:
You can use a table with a dictionary and then use a foreign key,
You can use the constraint to check the inserted value
You can use a domain (the field is in the type of Your domain, and the domain is based on
proper constraint)
You can use trigger (before insert or update)
etc.
To put this a different way, Postgres is a database, not a user-interface
library. It doesn't have dropdown lists, text boxes, labels and all that. It is not directly usable by a human that way.
What PG can do is provide a stable source for data used by such widgets. Each widget library has its own rules for how to bind (that is, connect) to a data source. Some let you directly connect the visual component, in this case, the dropdown widget, to a database, or better, a database cursor.
With Postgres, you can create a cursor, which is an in-memory window into the result of a SELECT query of some kind, that your widget or favorite programming language binds to. In your example, the cursor or widget binding would be to the result of a "SELECT student_type FROM student_type" query.
As an aside, the values for "student_type" should not be stored only in
"student". You should have a normalized table structure, which here would give you a "student_type" table that holds the three choices, one per row. (There
are other ways to do this.) The values you specified would be the primary key column. (Alternatively, you'd have those values in a UNIQUE column with a
surrogate key as the primary key, but that's probably overkilling for a simple
lookup table.) The "student.student_type" column would then be a foreign key
into the "student_type.student_type" column.
I have two tables
Normally, I would set them up as:
Classes
--------------
ClassID int autoinc
ClassName string
Session
--------------
SessionID int autoinc
SessionName string
SessionStart date
SessionEnd date
ClassID int FK
I would then query the sessiontable and join the classes table on classid.
In setting this up using CoreData do I still need the ClassID? I see that I can setup a relationship, but it doesn't seem to link to a specific column... only a table..
Your thinking is a a little database-oriented, which is no bad thing, but a Core Data schema isn't a relational database schema. You need to think in terms of objects, not tables and columns. You have two entities, not two tables.
The framework itself handles generating unique identifiers for each object. This identifier is really just an implementation detail. Create the objects, define the relationships, and Core Data will handle the rest, including creating bridge tables to handle many-to-many relationships.