jpa Using WHERE clause - jpa

I have 2 entities:
#Entity
public class Elements implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Owner owner;
}
#Entity
public class Owner implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(fetch=FetchType.LAZY)
List<Elements> elements;
}
Suppose I want to fetch all elemets bellonging to the owner from Elements Table and therfore I use:
TypedQuery query=em.createQuery("SELECT elem FROM Elements elem WHERE
elem.owner:=elemOwner", Elements.class);
query.setParameter("elemOwner", ownerObjectFetchFromDataBase);
List<TrendUsers> userList=query.getResultList();
But I get the following error:
Comparisons between 'BLOB' and 'BLOB' are not supported. Types must be comparable. String types must also have matching collation.
If collation does not match, a possible solution is to cast operands to force them to the default collation...
Is there any way I can Select from Elements Table and in the WHERE clause use object (and not just String,int...)?
(p.s I also tried the query below and it didn't work:
TypedQuery query=em.createQuery("SELECT elem FROM Elements elem WHERE elem.owner.id:=elemOwner", Elements.class);
query.setParameter("elemOwner", ownerObjectFetchFromDataBase.id);
List userList=query.getResultList();
)
Thanks

You need to mark the Owner als a ManyToOne.
#Entity public class Elements implements Serializable {
...snip ...
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="OWNER_ID")
private Owner owner;
}
#Entity public class Owner implements Serializable {
.. snip ...
#OneToMany(fetch=FetchType.LAZY, mappedBy="owner")
List<Elements> elements;
}
Right now you try to store the serialized owner in Blob. Thats not what you want ;-)
enjoy
Edit: included fix by xatavt

Related

Querying revisions of nested object using spring-data-envers

I'm trying to implement entity auditing in my Java Spring Boot project using spring-data-envers. All the entities are being created as they should, but I've come up against a brick wall when executing the query.
parentRepository.findRevisions(id).stream().map(Parent::getEntity).collect(Collectors.toList());
During this select the repository is supposed to fetch info also from the child entity, instead I get unable to find <child object> with {id}.
According to my experiments categoryId is being searched in the Category_Aud table, instead of the actual table with desired data.
Code snippets:
#Data
#Entity
#Audited
#NoArgsConstructor
public class Parent {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Enumerated(EnumType.STRING)
private Status status;
#Enumerated(EnumType.STRING)
private Type requestType;
private String fullName;
#ManyToOne
#JoinColumn(name = "child_id")
private Child child;
}
#Data
#Entity
#Audited
#NoArgsConstructor
public class Child {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
}
I've extended Parent with RevisionRepository
#Repository
public interface ParentRepository extends RevisionRepository<Parent, Long, Long>, JpaRepository<Parent, Long>
And annotated my SpringBootApplication entry class with:
#EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
I couldn't find any explanation for this so far, how can make parentRepository get what I need?
The underlying problem here is that the reference from a versioned entity isn't really properly defined. Which variant of the reference should be returned? The one at the start of the version you use as a basis, the one at the end? The one that exists right now?
There are scenarios for which each variant makes sense.
Therefor you have to query the revisions yourself and can't simply navigate to them.

Spring Data JPA Projection nested list projection interface

I have a question about usage of nested list projection interface. I have two entity (Parent and child) (they have Unidirectional association)
Parent =>
#Table(name = "parent")
#Entity
public class ParentEntity {
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
// other fields........
}
Child =>
#Table(name = "child")
#Entity
public class ChildEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#NonNull
private String name;
#NonNull
#ManyToOne(fetch = FetchType.LAZY)
private ParentEntity parent;
// other fields........
}
I have two projection interface for select specific columns.
ParentProjection =>
public interface ParentProjection {
String getName();
Set<ChildProjection> getChild();
}
ChildProjection =>
public interface ChildProjection {
String getId();
String getName();
}
I want to take list of ParentProjection which includes with list of ChildProjection.
Repository query like that =>
#Query("select p.name as name, c as child from ParentEntity p left join ChildEntity as c on p.id = c.parent.id")
List<ParentProjection> getParentProjectionList();
This query works, but it selects all columns of ChildEntity, and map only id, name propeties to ChildProjection. (generated query selects all columns, but i want to select only id and name columns)
How can i select only id and name columns (select specific columns for nested list projection interface) and map to ChildProjection fields (using with #Query) ?
Note: I don't need to use class type projection.
You need to add the OneToMany relation to ParentEntity and annotate with Lazy.
Hope it helps (i have tried this).

Query for joins in Spring JPA

I have the below entities
#Entity
#Getter
#Setter
public class Aggregate {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(mappedBy = "aggregate")
private Set<Single> singleSet;
}
#Entity
#Getter
#Setter
public class Single {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private String id;
private Integer number;
#ManyToOne
#JoinColumn(name = "agg_id")
private Aggregate aggregate;
}
I also have the below repository
public interface AggregateRepo extends CrudRepository<Aggregate, Long> {
}
I want to return all associated Single records where number in object Single is equal to some random number
I am assuming that the query will be something like this
public interface AggregateRepo extends CrudRepository<Aggregate, Long> {
public List<Single> findBySingleSet_Number(Integer number);
}
However when I try to use Intellij to complete my named query it always populates like this
public interface AggregateRepo extends CrudRepository<Aggregate, Long> {
public List<Single> findBySingleSet_Empty_Number(Integer number);
}
I am wondering what the Empty stands for ?
Also should I create another Single repository since the query is related to returning Single records.

EntityManagerSetupException for multiple joins and a sub query for NamedQuery

I am trying to write a NamedQuery with multiple joins and one sub-Query.
These are my Entities (I have removed most of the columns so that Question doesn't get too long and reader wouldn't need to go through unnecessary columns)
#Entity
public class progressEntry implements Serializable {
#Id
#GeneratedValue
private int id;
}
#Entity
public class KnowledgeTransfer implements Serializable {
#Id
#GeneratedValue
private int id;
#ManyToOne
private progressEntry pEntry;
}
#Entity
public class ColleagueActivity implements Serializable {
#Id
#GeneratedValue
private int id;
#ManyToOne
private KnowledgeTransfer knowledgeTransfer;
#ManyToOne
private College college;
}
#Entity
public class College implements Serializable {
#Id
#GeneratedValue
private Integer id;
private Integer studentNumber;
}
When I wrote the Native Query for this one, it works fine but I was wanted to learn how to write a Named Query with this one.
Here is what I tried which throws an Exception:
select progressEntry p where p.id in (select kt.progressEntryId from KnowledgeTransfer kt join ColleagueActivity cc on cc.ktid=kt.id join College c on c.id=cc.colleagueId where c.student.studentNumber= :studentNumber)
Please let me know if there is any more information that you would like me to post.
Thanks in advance.

Single Table Inheritance Query

i have an existing table for TransactionLogs which is either links to a External or to a InternalType. the id's corresponding to the cash adjustment & game transaction are stored in a single column called transaction id and a separate column called type indicates which table is it linked to
Because of the nature of the existing table, i mapped it in a single table inheritance:
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.INTEGER)
public class TransLog implements Serializable {
#Id
#GeneratedValue
private Long id;
private Integer type;
// getters and setters
}
#Entity
public class InternalAdjustmentTransLog extends TransLog {
#ManyToOne
#JoinColumn(name = "TransID", nullable = false)
private InternalAdjustmentRecord internalAdjustmentRecord;
// getters and setters
}
#Entity
public class ExternalTransLog extends TransLog {
#ManyToOne
#JoinColumn(name = "TransID", nullable = false)
private ExternalAdjustmentRecord externalAdjustmentRecord;
}
each of these two subclasses has their subclasses with defined descriminator values..
With the setup given above, there are instances that i need to get a unified data of both
internal and external records. What is the best way to accomplish this? at first i thought it would be enough to use the TransLog as the root class for the query (i'm using jpa criteria). however, i need to get TransId (which are defined in the subclasses and points to 2 different objects of no relationship).
Thanks.
You can make abstract method in TransLog that returns what you need and implement it in both subclasses.