Probably the guys who write documentation are very sleepy all the time, since it is not clear why everything always ends at half the example. Here is an example from the docks, like an example, and on the other hand a piece of stupid, unfinished code:

CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Metamodel m = em.getMetamodel(); EntityType<Pet> Pet_ = m.entity(Pet.class); EntityType<Owner> Owner_ = m.entity(Owner.class); Root<Pet> pet = cq.from(Pet.class); Join<Owner, Address> address = cq.join(Pet_.owners).join(Owner_.addresses); 

Well, they wrote how to call a join, and what to do with it? What is the address? What kind of person is that? Where to put it? HOW TO POINT BY WHAT AREA DO I WANT TO MAKE A JOIN? Or is this interface endowed with intelligence and he himself knows how and by what field when to join? Who faced type-safe queries and joins, give an example of how to finish writing a full join request to indicate that I want to join the field, because I no longer have the strength to play these riddles and guesswork with documentation of hibernates.

Update 1 : Just that I found an example with the construction of records in the criteria, off the docks hibernate.

Example 9.10. Example with Collections

 CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class ); Root<Person> personRoot = person.from( Person.class ); Join<Person,Order> orders = personRoot.join( Person_.orders ); Join<Order,LineItem> orderLines = orders.join( Order_.lineItems ); 

This is all ... this is all an example. Wonderful. Why is it needed? What did I learn from him? Yes, I did not know. This is just half of the unfinished code. Maybe someone has a decent source where you can study type-safe queries?

Update 2 : The answer to the question if someone will have difficulty creating type-safe queries using JOIN.

 @Override public List<Menu> getAllFromPlace(Long id){ CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<Menu> query = builder.createQuery(Menu.class); Root<Place> root = query.from(Place.class); Join<Place,Menu> menu = root.join(Place_.menus); query.select(menu).where(builder.equal(root.get(Place_.id), id)); List<Menu> menus = em.createQuery(query).getResultList(); return menus; } 

    2 answers 2

    Suppose we have entities between which there is a "Один ко Многим" relationship - Man - Car , respectively:

     class Man { public virtual string Name { get; set; } public virtual IList<Car> Cars { get; set; } } class Car { public virtual string Brend { get; set; } public virtual Man Man { get; set; } } 

    You have several options for performing Join in Nhibernate .

    Option 1

    In the simplest case, it is enough to call the Fetch() method, in which you can specify a related entity that needs to be loaded along with the main one.

    In our case, when receiving Car entities from the Car entity database, the Man entities associated with it will be loaded, this LINQ query will be converted into a SQL query with the Join statement.

     var cars = session.Query<Car>().Where(p => p.Brend == "BMW").Fetch(p => p.Man).ToList(); 

    Option 2

    Use SQL query.

     // Пишем SELECT. var query = "SELECT * FROM Cars INNER JOIN People ON Cars.ManID" = People.ID WHERE Cars.Brend = 'BMW'"; // Выполняем его через Nhibernate. var cars = session.CreateSQLQuery(query).List<Car>(); 
    • I just had to replace this option with type-safe queries, I already updated the question with the correct answer) - raviga
    • Please note that the question was asked about Hibernate , and you answered about NHibernate . Libraries, of course, are similar - but the languages ​​are different! :) - Pavel Mayorov
    • Pavel, I already noticed it later, but their APIs are identical. - sp7

    I answer theoretically, since I myself did not work with Hibernate . (In addition, the practical solution you already seem to have found)

    Well, they wrote how to call a join, and what to do with it? What is the address? What kind of person is that? Where to put it? HOW TO POINT BY WHAT AREA DO I WANT TO MAKE A JOIN? Or is this interface endowed with intelligence and he himself knows how and by what field when to join?

    Do not panic. Look at the request: in it you specify things like Pet_.owners and Owner_.addresses . It is for them that the fields that join are taken.

    When you create an association (connection) between two entities, you specify its type, navigation properties and its display in the database.

    So, every Pet object has a collection of owners . Further, I do not know for sure - but, logically, the Owner object should have a collection of pets . In this case, this relationship is a many-to-many relationship. Such links are displayed in the database on an additional table.

    Accordingly, when a .join(Pet_.owners) is done in a query, two joins with this intermediate table go to the database, something like this:

     Pets p JOIN Pets_Owners po ON p.Id = po.PetId JOIN Owners o ON o.Id = po.OwnerId 

    Alternatively, when an Owner object can have only one Pet . In this case, this relationship is a one-to-many one-way type, and it is assigned a separate field in the Owners table, which is a foreign key.

    In this case, when the request is done .join(Pet_.owners) - a simple join to the database takes place at the foreign key specified in the association:

     Pets p JOIN Owners o ON o.PetId = p.Id 

    Thus, when working with ORM, one should not think about any "fields" at all - if only the database is not inherited, then its entire structure can be entirely created by ORM in the form in which it is necessary.

    When working with ORM, you should think in terms of associations and navigation properties.