I could not make a better title, if anyone can do it please, help me out! Same for tags.
I've made a JPQL to bring me one Object with a List of other Objects.
The thing that's happening is.
I've got 2 items in Novidade(DB).
I've got 2 items in ComentarioNovidade(DB).
1 of the items from Novidade, connects to all 2 items from ComentarioNovidade. The other has no ComentarioNovidade related.
JPQL returns a List of Novidade (it's supposed to be)
I'm trying to make it return one Novidade with all ComentarioNovidade in it if it has any.
It's returning 3 Objects containing Novidade and ComentarioNovidade separated.
My JPQL is like this:
from Novidade as n left outer join n.comentariosNovidade
The class Novidade:
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="CodNovidade")
private Integer codNovidade;
#Column(name="Mensagem")
private String mensagem;
#Column(name="CodigoCidade")
private int codCidade;
#Column(name="CodigoBairro")
private int codBairro;
#Column(name="MesmoBairro")
private String mesmoBairro;
#OneToMany
#JoinColumn(name="CodNovidade")
private List<ComentarioNovidade> comentariosNovidade;
The class ComentarioNovidade:
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="CodComentarioNovidade")
private Integer codComentarioNovidade;
#Column(name="Comentario")
private String comentario;
#ManyToOne
#JoinColumn(name="CodNovidade")
private Novidade novidade;
#ManyToOne
#JoinColumn(name="CodUsuario")
private Usuario usuario;
A friend helped me out with that.
My JPQL ended up like this:
select distinct n from Novidade as n left outer join fetch n.comentariosNovidade
Related
This question already has answers here:
Infinite Recursion with Jackson JSON and Hibernate JPA issue
(29 answers)
Closed 3 years ago.
straight to the point:
I have a group that contains projects. I want that association to be handle with a foreign key, which is why it has a mappedby tag. My issue is that if I query for groups I get into an inifinite loop where the group lists the projects which contain the group which list the project which again contains the group.....and so on. My entities (minimal version):
#Entity
public class DBGroup {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
#OneToMany(mappedBy = "group",cascade=CascadeType.ALL,fetch = FetchType.EAGER)
private List<Project> projects = new ArrayList<>();
}
#Entity
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn//added this because i read somewhere this would help somehow but it didnt
private DBGroup group;
}
Can anyone help on how to avoid that loop? If I change the fetchtype to lazy in DBGroup I get a LazyInitializationEXception.
Any help is appreciated.
When the transaction ends you obtain an LazyInitializationEXception for all objects you didn't fetch.
If you get the object with a query add join fetch like:
select p from Project p join fetch p.group g
You can fetch a list via code calling the size method before exit the ejb.
Use FetchType.LAZY all time you can for prevent this especially if is a list.
I'm a beginner on JPA and I don't know pass result of a query to attribute entity.
Let me explain in one example:
I have an entity called Team, and another called Players:
The player is children of Team.
Class Team:
public class Team{
...
(relationship with Player has been hidden)
...
#Column(name = "AMOUNT_PLAYERS")
private Short amountPlayers;
#Column(name = "AMOUNT_FIRSTSTRING_PLAYERS")
private Short amountFirstStringPlayers;
#Column(name = "AMOUNT_SECONDSTRING_PLAYERS")
private Short amountSecondStringPlayers;
...
}
Class Player:
Public class Player{
...
#Column("STATUS_PLAYER")
private Short statusPlayer;
...
}
I have two questions about this.
1) In the amountPlayers, I want number total of player from this team;
In the amountFirstStringPlayers, I want number total of players (first-string) with statusPlayer of Player equals 1;
And in the amountSecondStringPlayers, I want number total of players (second-string) with statusPlayer of Player equals 2;
How I can get this values when I Find entity with JPA.
Example:
SELECT team FROM Team team
When I execute this, I want amountPlayers, amountFirstStringPlayers and amountSecondStringPlayers.
2) Put the resultQuery in an attribute of an entity, on an entity is a good practice?
You can use hibernate formula which are very convenient for these cases where you dont really need to persist these computed datas.
ex :
#Formula("(select count(*) from Player p where p.team_id = id)")
private Short amountPlayers;
#Formula("(select count(*) from Player p where p.team_id = id and p.statusPLayer=1)")
private Short amountFirstStringPlayers;
#Formula("(select count(*) from Player p where p.team_id = id and p.statusPLayer=2)")
private Short amountSecondStringPlayers;
Formula accepts sql string as parameter and here in the example id is the id of the current entity. You must replace with your entity id name and column.
If you don't want to use Formula you can also compute these values in memory based on players relation in your team entity.
ex:
#OneToMany(mappedBy="team")
private List<Player> players; // Here your onetomany association
public short getAmountPlayers(){
return players!= null ? players.size() : 0;
}
Say I want to get all rows of the MyEntity that have an id lower than 10. This entity contains a list of Another entity. I would like this list to be fetched only by a subset of the listAnother. This subset containing only Another where the user contained in it is a specific one.
Basically in SQL it would be like this :
SELECT * FROM myentity m
LEFT JOIN another a
ON m.idTable=a.my_entity
AND a.user = "test1"
WHERE m.idTable < 10;
I didn't manage however to translate this query to jpql.
My entities being like this :
#Entity
public class MyEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int idTable;
#OneToMany(mappedBy = "myEntity")
private List<Another> listAnother;
}
#Entity
public class Another implements Serializable {
#Id
private int idAnother;
// bi-directional many-to-one association to Thethread
#ManyToOne(fetch = FetchType.LAZY)
private MyEntity myEntity;
#ManyToOne(fetch = FetchType.LAZY)
private User user;
}
#Entity
public class User implements Serializable {
#Id
private String username;
}
In jpa I could do this :
SELECT m FROM MyEntity where m.idTable < 10;
And then for each entity I get from this list call this:
SELECT a FROM Another Where a.user.username=:'test' AND a.myEntity=:entity;
However I would like to do it all at once in one query. Can I do this with criteria ? I didn't take the time to learn it but if it's possible then I will.
JPQL and Critaria API are equal in terms of what you can express with them. What is possible with JPQL is possible with Criteria and vice versa.
With JPQL, you can simply combine your 2 queries into one in this way:
SELECT a FROM Another a Where a.user.username=:test AND a.myEntity.idTable < 10
You can use dot notation (.) to join multiple entities in the query, provided that the relationship is X-to-one. If you have X-to-many relationship, you need to use JPQL JOIN, which is not very complicated. Example with (LEFT) JOIN:
SELECT m FROM MyEntity m LEFT JOIN m.listAnother a Where a.user.username=:test AND m.idTable < 10
The result is of course not equal - in first case you will get list of Another entities and you can get MyEntity by a.myEntity, in the second case you will get list of MyEntity, which all have at least one Another entity with given user
In hibernate you can use Filters and FilterJoinTable. Here you can read how to do that. Similar problem was solved here.
You need to extend the logic which you applied to check the username (a.user.username=:'test') which was for many-to-one relation between anything and user by taking it one level up to myEntity and then using it for one-to-many relation as well -
SELECT m FROM MyEntity where m.idTable < 10 and (m.listAnother.user.username=:'test')
The join condition "m.listAnother.myEntity=:entity" wouldn't be needed now as in our query we have started from the specific myEntity and then moved down to listAnother.user.username .
I don't have the table definitions to try this query myself, exact SQL may require some tweaks - but logically it should work like the way I showed above, i.e. just the way you joined Another with User, the same way you can join MyEntity with Another by just traversing down the child listAnother.
I want to create a HQL Query that can access Attributes of a Set of spezified Objects, let me explain via a short example:
Class Organization
public class Organization ...{
private int orgid;
private Set<DomainValue> languages = new HashSet<language>(0);
private Set<Address> adresses = new HashSet<Address>(0);
...
}
Class Address
public class Address implements java.io.Serializable {
private int addressId;
private String city;
private String postalCode;
private String streetName;
private String houseNumber;
...
}
Language
public class Orgunitlanguage implements java.io.Serializable {
private int orgLanguageId;
private Orgunit orgunit;
private Integer languageCd;
...
}
These examples are code snippets of working hibernate POJOs. So i have an organization that can have multiple addresses and languages.
I want the user to specify the search criteria, but limit them to one of each kind, so only one language, one postalcode etc.
lets say the user wants english organizations with a housenumber 22
so i would build a hql query like this:
"from organization o where o.languages.languageCd = 1 AND o.addresses.housenumber = 22"
Well and that dosen't work (illegal syntax) how do i access these Sets in the right way? Keep in mind i want to access a specific attribute and not just the whole object (which is really easy).
I can't seem to find a documentation that i understand so a little explaination would be nice.
Proper way to query on collections would be like this
from Organization o join o.languages l join o.addresses a where l.languageCd = 1 AND a.housenumber = 22
However, this query will return any organization that has at least one language with languageCd = 1 and at least one address with housenumber = 22. It will not filter out the languages and addresses that don't fit the criteria. Check this answer for a little more explanation on this.
I have Hibernate generated classes that contain other classes -
public class BookLoans implements java.io.Serializable {
private BookLoansId id;
private Borrower borrower;
private LibraryBranch libraryBranch;
private Book book;
private Date dateOut;
private Date dueDate;
}
where BookLoansId is -
public class BookLoansId implements java.io.Serializable {
private int bookId;
private int branchId;
private int cardNo;
}
which are primary keys in the tables Book, LibraryBranch and Borrower respectively. When I run this query -
sessionFactory.getCurrentSession().createSQLQuery(
"select * from library.tbl_book_loans l where cardNo = 4");
Hibernate returns a list of Object[] elements. If I try to iterate through this list, I get null objects. I've tried a couple of different methods from here and here.
Is there any way to find out how the objects are arranged within each Object[]?
To directly map the query result to an entity objct use addEntity(BookLoans.class);
sessionFactory.getCurrentSession().createSQLQuery(
"select * from library.tbl_book_loans l where cardNo = 4")
.addEntity(BookLoans.class);
See the docs(16.1.2. Entity queries):
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querysql.html
However the result of nulls you get from your attempt is strange. Hibernate should give you List of Objects arrays where each Object array represents the fields in one row of the result set. Check if the query actualy returns something.
I solved this by using HQL:
from library.tbl_book_loans where borrower.cardNo = 4
Hibernate now correctly populates all mapped entities.