How to do an inner join in Prisma ORM? - prisma

Let there be 2 relations A and B.
There's a 1:n relationship, where for each A there can be multiple Bs.
This means that B has a foreign key to A.
How do I using Prisma ORM query to find all Bs with their A that have an A (so exclude all Bs that don't have an A)?
In SQL it would be something like:
SELECT * FROM "B" INNER JOIN "A" ON "A".id = "B".a_id;

Models should be declared this way:
model A {
id Int #id
b B[]
}
model B {
id Int #id
a_id Int
a A #relation(fields: [a_id], references: [id])
}
and the query could be this one
const a = await prisma.a.findMany({
// bring back the related B's
include: {
b: true,
},
});

Related

Override column selection in jpa

I need to select an integer column (int) by left joining its entity.
When there are no rows, its value is "null", what I need is to have 0 instead of null.
I searched for an annotation or a way to override the select query with no result. Note that I'm using eclipselink.
I am searching for something that always makes the selection of the column "coalesce(columnName,0)" instead of columnName.
EDIT:
A code Sample:
public class parent{
#Id
private int id;
private String field1;
private String field2;
private List<Child> children;
}
public class Child{
#Id
private int id;
private int myNumber;
private String field;
}
The JPA Query is similar to
SELECT p FROM parent p LEFT JOIN p.children c ON c.field = 'aaa' WHERE p.field1 = 'bbb'
The translation of this query would be:
SELECT t0.id, t0.field1, t0.field2, t1.id, t1.myNumber, t1.field
FROM parent t0 LEFT OUTER JOIN child t1 on t0.id = t1.parent_id AND t1.field = 'aaaa
WHERE t0.field1 = 'bbb'
In the case where there are no rows in CHILD, the field: t1.myNumber will have the value null.
To fix it, in Sql statement, normally I will use coalesce(t1.myNumber,0). So the query will be:
SELECT t0.id, t0.field1, t0.field2, t1.id, coalesce(t1.myNumber,0), t1.field
FROM parent t0 LEFT OUTER JOIN child t1 on t0.id = t1.parent_id AND t1.field = 'aaaa
WHERE t0.field1 = 'bbb'
What I need is to accomplish this result using some annotation, or any other tool if exists, whithout changing the JPA query if possible.

EF6 one to one fluent API configuration

I am struggling to map my EF6 classes to table structure. Here is my table structure:
**TableA:**
Id (PK),
Name,
BId (FK to TableB), NULLABLE
**TableB:**
Id (PK),
Prop1,
Prop2
My classes are:
class TableA
{
int Id;
string Name;
int BId;
TableB bObject;
}
//TableB doesnt need to know about TableA
class TableB
{
int Id;
string prop1;
string prop2;
}
I want to use a configuration for TableA to something like:
HasRequired(a => a.bObject).WithOptional().HasForeignKey(a => a.BId);
However, this is not working. How do I fix this?
Thanks
Vik

Querying EXISTS in many to many relations in Criteria API

Having two entity classes with a many to many relation, I am trying to create query which tests the existence of any relationship for all entities from one table. I am stuck because it seems that there is no way to refer to the JoinTable through the Criteria API.
Example entities:
#Entity
#Table(name="man")
public class Man {
#Id
#GeneratedValue
private Long id;
}
#Entity
#Table(name="woman")
public class Woman {
#Id
#GeneratedValue
private Long id;
#ManyToMany
#JoinTable(
name="man_woman",
joinColumns=
#JoinColumn(name="woman_id", referencedColumnName="id"),
inverseJoinColumns=
#JoinColumn(name="man_id", referencedColumnName="id")
)
private Set<Man> men;
}
I would like to create a query using criteria API which would result in SQL such as:
select m.id,
case when exists(select * from man_woman mw where mw.man_id=m.id) then 1 else 0
from man;
The best I have come up with so far is the following:
CriteriaQuery<Tuple> criteriaQuery = criteriaBuilder.createTupleQuery();
Root<Man> from = criteriaQuery.from(Man.class);
Subquery<Long> subquery = criteriaQuery.subquery(Long.class);
Root<Woman> sub_from = subquery.from(Woman.class);
SetJoin<Woman, Man> setJoin = sub_from.join(Woman_.men);
subquery.select(sub_from.get(Woman_.id));
subquery.where(from.in(setJoin.get(Man_.id)));
criteriaQuery.multiselect(from.alias("man_entity"),
criteriaBuilder.selectCase()
.when(
criteriaBuilder.exists(subquery)
, true)
.otherwise(false)
.alias("knows_any_women")
);
return em.createQuery(criteriaQuery).getResultList()
which results in SQL containing extra joins:
select m.id,
case when exists(select w.id
from woman w
inner join man_woman mw on w.id = mw.woman_id
inner join man m2 on m2.id = mw.man_id
where m.id in (m2.id)
)
then 1 else 0
from man;
I guess this statement would eventually be optimized to look like my desired one - but is there a way to make it simpler from the beginning?

#Embedded object gererating CROSS JOIN on JPQL

i'm try use JPA #Embedded object in Entity. That Embedded has #OneToOne relationsip, but wen i try get filter using JPQL. there is generating CROSS JOIN, but i expected INNER JOIN. See the axample:
#Entity
Class A{
#Id
Long id;
#Embedded
private B b;
}
#Emdeddable
Class B{
#OneToOne
private C c;
}
#Entity
Class C{
#Column
private name;
}
In database, the FK column to "C" table is in "A" table. When i try this JPQL: SELECT FROM a WHERE a.b.c.name = :name i expected JPA does the folowing: A inner join C on A.id=C.id, but JPA does A cross join B where A.id=B.id
I dont want put C relationship in entity A becouse my specific code organization. Have any solution to this? Is this a bug?

selecting existing and non existing joined entity at once

I have a join table looks like this.
EXCHANGE_RATE
------------------------------
ID BIGINT PK
SOURCE_CURRENCY_ID BIGINT FK
TARGET_CURRENCY_ID BIGINT FK
Mapped ExchangeRate.java
public class ExchangeRate {
protected ExchangeRage() {
this(null, null);
}
// for SELECT NEW
public ExchangeRate(Currency sourceCurrency, Currency targetCurrency) {
this.sourceCurrency = sourceCurrency;
this.targetCurrency = targetCurrency;
}
#Id private Long id;
#ManyToOne private Currency sourceCurrency;
#ManyToOne private Currency targetCurrency;
}
How can I list all existing and non existing ExchangeRates for given sourceCurrency?
For example,
There are three Currencies. A, B, and C.
There is already an ExhangeRate from A to B
With following method, if sourceCurrency is A,
public List<ExchangeRate> listExchangeable(Currency sourceCurrency) {
//
}
How can I get following list?
ExchangeRate {
id: 0
sourceCurrency: A
targetCurrency: B
},
ExchangeRate {
id: NULL
sourceCurrency: A
targetCurrency: C
}
Required Query
// get all exchange rates for a source currency
public List<ExchangeRate> listExchangeable(Currency sourceCurrency) {
Query qry = em.createQuery("select r from ExchangeRate r where
r.sourceCurrency = :sourceCurrency");
qry.setParameter("sourceCurrency", sourceCurrency);
return qry.getResultList();
}
for non existing ExchangeRates for given sourceCurrency
Query qry = em.createQuery("select r from ExchangeRate r where
r.sourceCurrency != :sourceCurrency");