powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / jpql как вернуть min max в одном запросе ?
25 сообщений из 35, страница 1 из 2
jpql как вернуть min max в одном запросе ?
    #39256791
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
доброе утро

собственно есть общий вопрос : как вернуть что то произвольного типа ?



Код: java
1.
2.
3.
   @Modifying
    @Query("SELECT max(s.actionDatetime), min(s.actionDatetime) FROM #{#entityName} s")
    List<Object[]> getMaxMinIdByActionDatetime();



Это вернет массив из двух объектов вида List<Object[]> ...

sql будет такой

Код: java
1.
2.
3.
4.
5.
6.
Hibernate: 
    select
        max(shift0_.action_datetime) as col_0_0_,
        min(shift0_.action_datetime) as col_1_0_ 
    from
        shift shift0_



в java для работы с orm и базами нет ни пар ни каких то абстракций для результата выполнения произвольного запроса?!


можно как в ejb указать dto класс ?

или как минимум обвязка из
SqlResultSetMapping

http://docs.oracle.com/javaee/5/api/javax/persistence/SqlResultSetMapping.html

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
    Query q = em.createNativeQuery(
        "SELECT o.id AS order_id, " +
            "o.quantity AS order_quantity, " +
            "o.item AS order_item, " +
            "i.name AS item_name, " +
        "FROM Order o, Item i " +
        "WHERE (order_quantity > 25) AND (order_item = i.id)",
    "OrderResults");
    
    @SqlResultSetMapping(name="OrderResults", 
        entities={ 
            @EntityResult(entityClass=com.acme.Order.class, fields={
                @FieldResult(name="id", column="order_id"),
                @FieldResult(name="quantity", column="order_quantity"), 
                @FieldResult(name="item", column="order_item")})},
        columns={
            @ColumnResult(name="item_name")}
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39256803
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1,

JPQL спеку надо смотреть. Но HQL точно умеет:
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html
14.6. The select clause

Код: sql
1.
SELECT new OrderResults(max(s.actionDatetime), min(s.actionDatetime)) FROM #{#entityName};
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39256813
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я имел ввиду

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
public class TimeInterval {
    private LocalDateTime start;
    private LocalDateTime stop;

    public TimeInterval() {
    }

    
 

    public TimeInterval(Date start, Date stop) {
        this.start = LocalDateTime.ofInstant(start.toInstant(), ZoneId.systemDefault());
        this.stop =  LocalDateTime.ofInstant(stop.toInstant(), ZoneId.systemDefault());;
    }


 @Query("SELECT new ru.model.TimeInterval(max(s.actionDatetime), min(s.actionDatetime)) FROM #{#entityName} s")
    TimeInterval getMaxMinIdByActionDatetime();
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39256815
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1я имел ввиду
Что это принципиально меняет?
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39256817
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczAtum1,

JPQL спеку надо смотреть. Но HQL точно умеет:
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html
14.6. The select clause

Код: sql
1.
SELECT new OrderResults(max(s.actionDatetime), min(s.actionDatetime)) FROM #{#entityName};



Да я про это знаю ...

я как раз не про внутреннее преобразование в jpql а как бы сказать внешнее ...по типу SqlResultSetMapping - когда мы говорим что ответ нужно положить в структуру вида (и указываем вид )

но для примеров с SqlResultSetMapping - Это оверхад с бойлерплейт кодом

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
JPA 2.1 with @SqlResultSetMapping

With the arrival of JPA 2.1, we can use the @SqlResultSetMapping annotation to solve the problem.

We need to declare a result set mapping somewhere in a entity:

@SqlResultSetMapping(name="JediResult", classes = {
    @ConstructorResult(targetClass = Jedi.class, 
    columns = {@ColumnResult(name="name"), @ColumnResult(name="age")})
})
And then we simply do:

Query query = em.createNativeQuery("SELECT name,age FROM jedis_table", "JediResult");
@SuppressWarnings("unchecked")
List<Jedi> samples = query.getResultList();
Of course, in this case Jedi needs not to be an mapped entity. It can be a regular POJO.



http://stackoverflow.com/questions/13012584/jpa-how-to-convert-a-native-query-result-set-to-pojo-class-collection


может есть что то типа Project Lombok ?
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39256859
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
в Hibernate очень удобная штука есть - ResultTransformers
Код: java
1.
2.
3.
Query query = session.getNamedQuery("active processes")
	.setResultTransformer(Transformers.aliasToBean(CreditProcess.class));
List<CreditProcess> processes = query.list();


результиркющий бин - очычный pojo класс, не требующий никаких аннотаций, только геттеры и сеттеры
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257259
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://www.thoughts-on-java.org/result-set-mapping-complex-mappings/




Код: java
1.
SELECT b.id, b.title, b.author_id, b.version, a.id as authorId, a.firstName, a.lastName, a.version as authorVersion FROM Book b JOIN Author a ON b.author_id = a.id



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
@SqlResultSetMapping(
        name = "BookAuthorMapping",
        entities = {
            @EntityResult(
                    entityClass = Book.class,
                    fields = {
                        @FieldResult(name = "id", column = "id"),
                        @FieldResult(name = "title", column = "title"),
                        @FieldResult(name = "author", column = "author_id"),
                        @FieldResult(name = "version", column = "version")}),
            @EntityResult(
                    entityClass = Author.class,
                    fields = {
                        @FieldResult(name = "id", column = "authorId"),
                        @FieldResult(name = "firstName", column = "firstName"),
                        @FieldResult(name = "lastName", column = "lastName"),
                        @FieldResult(name = "version", column = "authorVersion")})})




Код: java
1.
2.
3.
4.
5.
6.
7.
List<Object[]> results = this.em.createNativeQuery("SELECT b.id, b.title, b.author_id, b.version, a.id as authorId, a.firstName, a.lastName, a.version as authorVersion FROM Book b JOIN Author a ON b.author_id = a.id", "BookAuthorMapping").getResultList();

results.stream().forEach((record) -> {
    Book book = (Book)record[0];
    Author author = (Author)record[1];
    // do something useful
});



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
SELECT a.id, a.firstName, a.lastName, a.version, count(b.id) as bookCount FROM Book b JOIN Author a ON b.author_id = a.id GROUP BY a.id, a.firstName, a.lastName, a.version


@SqlResultSetMapping(
        name = "AuthorBookCountMapping",
        entities = @EntityResult(
                entityClass = Author.class,
                fields = {
                    @FieldResult(name = "id", column = "id"),
                    @FieldResult(name = "firstName", column = "firstName"),
                    @FieldResult(name = "lastName", column = "lastName"),
                    @FieldResult(name = "version", column = "version")}),
        columns = @ColumnResult(name = "bookCount", type = Long.class))


List<Object[]> results = this.em.createNativeQuery("SELECT a.id, a.firstName, a.lastName, a.version, count(b.id) as bookCount FROM Book b JOIN Author a ON b.author_id = a.id GROUP BY a.id, a.firstName, a.lastName, a.version", "AuthorBookCountMapping").getResultList();

results.stream().forEach((record) -> {
    Author author = (Author)record[0];
    Long bookCount = (Long)record[1];
    System.out.println("Author: ID ["+author.getId()+"] firstName ["+author.getFirstName()+"] lastName ["+author.getLastName()+"] number of books ["+bookCount+"]");
});
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257269
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вопрос тогда такой - где хранить эти sql запросы ? в коде или вxml в базе ?

Код: java
1.
@Query("SELECT max(s.actionDatetime), min(s.actionDatetime) FROM #{#entityName} s")



где вы их храните ?

или в в виде хранимых процедур в БД ? тогда как вы их исполняете?
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257284
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://www.thoughts-on-java.org/result-set-mapping-hibernate-specific-mappings/

для hibernate

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
@PersistenceContext
private EntityManager em;

...

public void queryWithAuthorBookCountHibernateMapping() {
  Session session = (Session)this.em.getDelegate();
  ...
}


List<BookValue> results = ((Session)this.em.getDelegate()).createSQLQuery("SELECT b.id, b.title, b.version, a.firstName || ' ' || a.lastName as authorName FROM Book b JOIN Author a ON b.author_id = a.id")
    .addScalar("id", StandardBasicTypes.LONG).addScalar("title").addScalar("version", StandardBasicTypes.LONG).addScalar("authorName")
    .setResultTransformer(new AliasToBeanResultTransformer(BookValue.class)).list();

results.stream().forEach((book) -> {
    System.out.println("Book: ID [" + book.getId() + "] title [" + book.getTitle() + "] authorName [" + book.getAuthorName() + "]");
});
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257292
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если уже определился что все будет на sql / plsql

где хранить исходники этих самых sql запросов ?
относительно кода их исполнения?
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257326
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1 где хранить исходники этих самых sql запросов ? относительно кода их исполнения?
в коде. Т.к. это тоже код, только на SQL
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257501
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Atum1 где хранить исходники этих самых sql запросов ? относительно кода их исполнения?
в коде. Т.к. это тоже код, только на SQL
т.е если нужно подправить условии в sql строке - нужно пересбрать весь код на вашем проекте ?
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257520
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1,
Во первых большие проекты модульные.
Во вторых, вопрос:
Если вам надо поправить условие if зарплата > 2
то вам нужно будет пересобирать весь проект?
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257529
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хоть аннотации и позволяют, но хранить в запросы в коде очень неудобно. Хотя бы из-за кавычек.
Я лично всё, что занимает более одной строки, складываю в xml ресурсы. Вот, например, именованный hibernate запрос, возвращающий не-entity данные
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
<sql-query name="active processes">
	<!-- oracle приводит к верхнему регистру, а нам надо так, чтобы совпадало с именем свойств -->
	<return-scalar column="processId" type="long"/>
	<return-scalar column="creditId"/>
	...
	<![CDATA[
-- многоэтажный oracle-запрос
with 
credit as (
...
)
select ...
	]]>
</sql-query>


Использовать чистый jpql в данном случае не получится, так как там возможно трансформировать результаты только в entity. Кроме того, подобные запросы не требуют никакого дополнительного кода (addScalar), пример я привел выше.
Таким образом, все метаданные собраны в одно место и положены отдельно от кода, что довольно удобно.
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257538
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Изначально мой вопрос более философский

навеяно темами 6! летней давности

Hibernate performance — Ковальски, варианты?!

http://javatalks.ru/topics/32234?page=1

http://javatalks.ru/topics/19539?page=1

и этим видео

[youtube=
YouTube Video
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257558
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanra,
Если он большой, то все индивидуально.
Значит он должен в бд сидеть. Во вьюшке.
Мы же про CRUD.
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257587
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за ваш опыт ... да хранить либо в xml либо в ввиде plsql процедур в БД (как делаю сейчас)

просто еще раз - хибернейт , jpa, orm , crud это все не очень удобно ... :(? долго , как в разработке так и в поддержке ...


Мнимость удобства crud и orm - слабый контроль над генерируемым sql и огромный набор знаний

1) отличное знание и понимание sql
2) отличное знание того как работает Хибер (как джоинит , стоит запросы итд )


Нельзя просто так взять и использовать Хибер !

Вот мой пример в противовес тому что обычно приводят в книгах ! ( объектная модель : автор- книги - адрес )


я приду другой контр пример : попробуйте правильно составить entity модель и написать когда в таблицах есть дерево объектов!

Employee - сотрудник , есть связь с отделом и есть коллекция подчиненных и связь с руководителем

Самое простое всего три таблицы :

Нужно вытащить сотрудника по его id через jpql или критериа апи и вызвать его метод toString()

есть таблицы : Department - отделы :
Employee - сотрудник , есть связь с отделом и есть коллекция подчиненных и связь с руководителем
Shift - время прихода /ухода сотрудника на работу

Проблемы :

1 берем простой подход через spring data jpa Repository - есть метод findOne

Код: java
1.
2.
3.
4.
5.
6.
@Repository
public interface EmployeeRepository extends  JpaRepository<Employee,Integer>, JpaSpecificationExecutor<Employee> {

   @Query("select e from Employee e where e.id = :id") 
   Employee findByEmployeeId(@Param("id") Integer id );
}



Пишем тест

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
   @Test
    public void test1() {
        Employee employee = employeeRepository.findOne(2); //findOne(1)  подтянуть всю!!!! таблицу и все данные одни запросом !!!! Легко !?!
        System.out.println(employee);
        System.out.println(employee.getEmployees());
        System.out.println(employee.getShifts());
        
    }



получаем

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Hibernate: 
    select
        employee0_.id as id1_1_0_,
        employee0_.department_id as departme4_1_0_,
        employee0_.employee_id as employee5_1_0_,
        employee0_.name as name2_1_0_,
        employee0_.salary as salary3_1_0_,
        department1_.id as id1_0_1_,
        department1_.name as name2_0_1_ 
    from
        employee employee0_ 
    inner join
        department department1_ 
            on employee0_.department_id=department1_.id 
    where
        employee0_.id=?



и

Код: plsql
1.
2.
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165)



почему? потому что у Employee fetch = FetchType.LAZY

меняем

Код: java
1.
2.
  @ManyToOne(fetch = FetchType.EAGER)
    private Employee employeeId;



получаем все ок ! но при этом лишний запрос ...

теперь рассмотрим классический код EmployeeServiceImpl PersistenceContext

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
@Service
public class EmployeeServiceImpl implements EmployeeService {

    @PersistenceContext
    private EntityManager em;
    
    
    protected final EmployeeRepository repository;

    @Autowired
    public EmployeeServiceImpl(EmployeeRepository repository) {
        super();
        this.repository = repository;
    }

    @Override
    //@Transactional
    public Employee findByEmployeeId(Integer id) {
       TypedQuery<Employee> query = em
               .createQuery("select e from Employee e  where e.id = :id ",Employee.class) //   для проверки любого запроса 
               //createQuery("select e from Employee e JOIN FETCH e.employees b JOIN FETCH e.departmentId d where e.id = :id ",Employee.class)
               .setParameter("id", id);
        return query.getSingleResult();
    }
    
}



та же ошибка !!!!!!

Повторяю я просто хочу запросить пользователя ... без его коллекций ?! !!!

и вызвать

public String toString() {
return "Employee{


вся засада в простом : employeeId инициализируется через прокси и ждет когда его дернут ... даже если нам нужно лишь проверить id


а если у нас транзакция закрылась - вообще беда !!!





Исходные данные


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
drop table if exists department;
create table department (
      id   int          not null    AUTO_INCREMENT
    , name varchar(255) not null
    , primary key (id)
);


insert into department (
    id, name
) values
  (1, 'IT')
, (2, 'Management')
, (3, 'CTO')
;




Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
import java.io.Serializable;
import java.util.Collection;
import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import lombok.Data;
import org.hibernate.annotations.FetchMode;


@Entity
@Table(name = "department")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Department.findAll", query = "SELECT d FROM Department d"),
    @NamedQuery(name = "Department.findById", query = "SELECT d FROM Department d WHERE d.id = :id"),
    @NamedQuery(name = "Department.findByName", query = "SELECT d FROM Department d WHERE d.name = :name")})
public class Department implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    
    @Basic(optional = false)
    @Column(name = "name")
    private String name;
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "departmentId" , fetch = FetchType.LAZY)
    //@org.hibernate.annotations.Fetch(FetchMode.JOIN)
    private Collection<Employee> employeeCollection;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Collection<Employee> getEmployeeCollection() {
        return employeeCollection;
    }

    public void setEmployeeCollection(Collection<Employee> employeeCollection) {
        this.employeeCollection = employeeCollection;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 89 * hash + Objects.hashCode(this.name);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Department other = (Department) obj;
        if (!Objects.equals(this.name, other.name)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Department{" + "id=" + id + ", name=" + name + '}';
    }


    
}




Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
 drop table if exists employee;
 create table employee (
   id            int             not null    auto_increment,
   department_id int             not null,
   employee_id   int,
   name          varchar(255)    not null,
   salary        bigint unsigned not null,
   primary key (id),
   constraint FK_department_id_department_id foreign key (department_id)
  references department (id),
  constraint FK_employee_id_employee_id foreign key (employee_id)
   references employee (id)
 );

 insert into employee (
     id, department_id, employee_id, name, salary
 ) values
   ( 1, 3,  null, 'Mapiro',      100000000 )
 , ( 2, 1,  1,    'Vatyushkin',    19000000 )
 , ( 3, 1,  2,    'Horin',         21000000 )
 , ( 4, 1,  3,    'Sinitsin',      12000000 )
 , ( 5, 1,  3,    'Ustovalov',    10000000 )
 , ( 6, 1,  3,    'Fox',           10000000 )
 , ( 7, 1,  6,    'Kalnikov',      14000000 )
 , ( 8, 1,  2,    'Senderov',   15000000 )
 , ( 9, 1,  8,    'Prushnikov',  10000000 )
 , (10, 1,  8,    'Zaitsev',       15000000 )
 , (11, 1,  8,    'Gulshaev',   10000000 )
 , (12, 2,  1,    'Ignotogin',       15000000 )
 , (13, 2, 12,    'Lyabovsky',     12000000 )
 , (14, 2, 12,    'Ivanova',        15500000 )
 , (15, 3,  1,    'Krasavica',      8000000 )
 , (16, 3, 15,    'Uborshik',       8500000 )
 ;




Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;


@Entity
@Table(name = "employee")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e"),
    @NamedQuery(name = "Employee.findById", query = "SELECT e FROM Employee e WHERE e.id = :id"),
    @NamedQuery(name = "Employee.findByName", query = "SELECT e FROM Employee e WHERE e.name = :name"),
    @NamedQuery(name = "Employee.findBySalary", query = "SELECT e FROM Employee e WHERE e.salary = :salary")})
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    
    @Basic(optional = false)
    @Column(name = "name")
    private String name;
    
    @Column(name = "salary")
    private long salary;
    
    @OneToMany(mappedBy = "employeeId" ,fetch = FetchType.LAZY)
    //@org.hibernate.annotations.Fetch(FetchMode.JOIN)
    private List<Shift> shifts;
    
    @Basic(optional = false)
    @JoinColumn(name = "department_id", referencedColumnName = "id", nullable = false )
    @ManyToOne(fetch = FetchType.EAGER , optional = false)
    //@org.hibernate.annotations.Fetch(FetchMode.JOIN)
    private Department departmentId;
    
    @OneToMany(mappedBy = "employeeId" , fetch = FetchType.LAZY)
    //@org.hibernate.annotations.Fetch(FetchMode.JOIN)
    private List<Employee> employees;
    
    @JoinColumn(name = "employee_id", referencedColumnName = "id" )
   // @org.hibernate.annotations.Fetch(FetchMode.JOIN)
    @ManyToOne(fetch = FetchType.LAZY)
    private Employee employeeId;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getSalary() {
        return salary;
    }

    public void setSalary(long salary) {
        this.salary = salary;
    }

    public List<Shift> getShifts() {
        return shifts;
    }

    public void setShifts(List<Shift> shifts) {
        this.shifts = shifts;
    }

    public Department getDepartmentId() {
        return departmentId;
    }

    public void setDepartmentId(Department departmentId) {
        this.departmentId = departmentId;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }



    public Employee getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(Employee employeeId) {
        this.employeeId = employeeId;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 97 * hash + Objects.hashCode(this.name);
        hash = 97 * hash + (int) (this.salary ^ (this.salary >>> 32));
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Employee other = (Employee) obj;
        if (!Objects.equals(this.name, other.name)) {
            return false;
        }
        if (this.salary != other.salary) {
            return false;
        }

        return true;
    }

    @Override
    public String toString() {
        return "Employee{" + "id=" + id + ", name=" + name + ", salary=" + salary + ", departmentId=" + (departmentId != null?departmentId.getId():"") + ", employeeId=" + (employeeId!=null? employeeId.getId() : "") + '}';
    }






Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.Data;
import org.springframework.context.annotation.Lazy;


@Entity
@Table(name = "shift")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Shift.findAll", query = "SELECT s FROM Shift s"),
    @NamedQuery(name = "Shift.findById", query = "SELECT s FROM Shift s WHERE s.id = :id"),
    @NamedQuery(name = "Shift.findByOperationType", query = "SELECT s FROM Shift s WHERE s.operationType = :operationType"),
    @NamedQuery(name = "Shift.findByActionDatetime", query = "SELECT s FROM Shift s WHERE s.actionDatetime = :actionDatetime")})
public class Shift implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "operation_type" , columnDefinition = "enum('enter','exit')")
    @Enumerated(EnumType.STRING)
    private OperationType operationType;
    @Basic(optional = false)
    @Column(name = "action_datetime")
    @Temporal(TemporalType.TIMESTAMP)
    private Date actionDatetime;
    @JoinColumn(name = "employee_id", referencedColumnName = "id")
    @ManyToOne (fetch =  FetchType.EAGER)
    private Employee employeeId;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public OperationType getOperationType() {
        return operationType;
    }

    public void setOperationType(OperationType operationType) {
        this.operationType = operationType;
    }

    public Date getActionDatetime() {
        return actionDatetime;
    }

    public void setActionDatetime(Date actionDatetime) {
        this.actionDatetime = actionDatetime;
    }

    public Employee getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(Employee employeeId) {
        this.employeeId = employeeId;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 29 * hash + Objects.hashCode(this.operationType);
        hash = 29 * hash + Objects.hashCode(this.employeeId);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Shift other = (Shift) obj;
        
        
        
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        if (this.operationType != other.operationType) {
            return false;
        }
        if (!Objects.equals(this.actionDatetime, other.actionDatetime)) {
            return false;
        }
        return Objects.equals(this.employeeId, other.employeeId);
    }

    @Override
    public String toString() {
        return "Shift{" + "id=" + id + ", operationType=" + operationType + ", actionDatetime=" + actionDatetime + ", employeeId=" + employeeId.getId() + '}';
    }

    
 
public boolean isStartOperation(){
    return OperationType.enter.equals(operationType); 
}




Для всех у кого есть желание по изучать как хибернейт делает прокси и стоит запросы по коду - исходники для mysql приложил ...

играться можно всеми параметрами +

Код: java
1.
2.
3.
4.
5.
@Basic(optional = false)

@OneToMany  fetch = FetchType.LAZY optional = false nullable = false 

@org.hibernate.annotations.Fetch(FetchMode.JOIN) 



еще раз проблематика - получить сотрудника вывести его на печать ...

получить сотрудника и список его подчиненных

получить сотрудника и список его подчиненных и ссылку на его начальника

итд



Код для теста :


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
@Configuration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SqlTaskTest.class})
@Log
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactory",
        transactionManagerRef = "transactionManager",
        basePackages = {"ru.repositories"})
public class SqlTaskTest {

    public static final Gson gson = new GsonBuilder().setPrettyPrinting().create();

    //Configuration
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        return configurer;
    }

    @Bean
    @Qualifier("dataSource")
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/db_test?zeroDateTimeBehavior=convertToNull");

        dataSource.setUsername("root");
        dataSource.setPassword("root");

        return dataSource;
    }

    @Autowired
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("dataSource") DataSource dataSource) {

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(true);
        

        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan(new String[]{
            "ru.entities",});
        em.setPersistenceUnitName("testPersistanceUnit");

        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());

        return em;

    }

    @Autowired
    @Bean(name = "transactionManager")
    @Qualifier("transactionManager")
    public PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory);
        return txManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.bytecode.use_reflection_optimizer", "false");
        properties.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        properties.setProperty("hibernate.hbm2ddl.auto", "validate");//update validate
        properties.setProperty("hibernate.show_sql", "true");
        properties.setProperty("hibernate.format_sql", "true");
        properties.setProperty("hibernate.connection.characterEncoding", "utf8");

        properties.setProperty("hibernate.connection.Useunicode", "true");

        properties.setProperty("hibernate.default_batch_fetch_size", "16");
        properties.setProperty("hibernate.max_fetch_depth", "3");
        properties.setProperty("hibernate.jdbc.fetch_size", "50");

        return properties;
    }

    @Autowired
    DepartmentRepository departmentRepository;
    @Autowired
    ShiftRepository shiftRepository;
    @Autowired
    EmployeeRepository employeeRepository;
    @Autowired
    DataSource dataSource;

    @Bean
    DepartmentService departmentService() {
        return new DepartmentServiceImpl(departmentRepository);
    }
    @Bean
    EmployeeService employeeService() {
        return new EmployeeServiceImpl(employeeRepository);
    }

    @Autowired
    DepartmentService departmentService;

    @Autowired
    EmployeeService employeeService;


...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257594
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1Мнимость удобства crud и orm
много букв не читал.
Ты на святое посягнул что ли? ))).
Тут же эта тема через раз.
А ты, насколько знаю - любишь спринг\орм\хибер.
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257621
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1просто еще раз - хибернейт , jpa, orm , crud это все не очень удобно ... :(? долго , как в разработке так и в поддержке ...
Мнимость удобства crud и orm - слабый контроль над генерируемым sql и огромный набор знаний

А вот возьми и напиши всё на JDBC с транзакциями, кешированием, кучей ассоциаций и потом вместе посмеёмся на сколько "проще" получилось.
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257650
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Atum1,
с одной стороны пишешь авторПовторяю я просто хочу запросить пользователя ... без его коллекций ?! !!!, а с другой - вот такой код
Код: java
1.
2.
3.
4.
5.
6.
7.
   @Test
    public void test1() {
        Employee employee = employeeRepository.findOne(2); //findOne(1)  подтянуть всю!!!! таблицу и все данные одни запросом !!!! Легко !?!
        System.out.println(employee);
        System.out.println(employee.getEmployees());
        System.out.println(employee.getShifts());
    }


вот же они, коллекции (employee.getEmployees(), employee.getShifts()).
employee выведется на консоль без вопросов, независимо от жадных и ленивых связей, а вот дальше - в зависимости от жадности метода employeeRepository.findOne
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257711
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Atum1Мнимость удобства crud и orm
много букв не читал.
Ты на святое посягнул что ли? ))).
Тут же эта тема через раз.
А ты, насколько знаю - любишь спринг\орм\хибер.

да и еще как люблю :)

на задчках типа crud вытащи все из базы вот тебе пример ...

просто в очередной раз 19285319 решил проверить что же там такое генерит Хибер взял не простой пример - дерево сотрудников и пришел а тихий ужас !

поднял пару старых 2010 года тем - посмотрел что новое появилось ... посмотрел видео .... ссылки все тут скинул ...

много букв не читал. - я бы попросил - потестить попробовать позапускать ...

то что сейчас представляет из себя Хибер - полный садоом ...

реально потом обдало холдным .... поясню :

1) модель правильную опиши ... а что если иногда нужно делать так а потом так (а модель то описывает исключительно одно поведение - она не гибкая , каскады , null значения , Lazy объектов и коллекций)

2) после этого начинай писать запросы на jpql | критериях

3) после этого погружайся в Мир увлекательного перфоманса и оптимизиции (101 трюк который должен знать каждый Хибер разработчик) ссылки я привел в топике .
(как кешировать jpql | критериях запросы , через граф апи, через кеши, через хинты итд , ) - нужно обязательно знать



Вместо того чтобы :

1) написать хранимку
2) построить ее план (оптимизировать ее в БД)
3) Вызвать из java кода - и каким то образом замапить на объект - или коллекцию ...
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257724
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1 то что сейчас представляет из себя Хибер - полный садоом ...
обычное дело. Ты познаёшь Мир и тебя шатает из стороны в сторону.
Выше сказали - сделай полный цикл примера без ОРМ и тогда у тебя наступин нирвана.
Просто одна критика одной стороны неконструктивна. Нужно as is to be - во все времена.
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257739
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum13) Вызвать из java кода - и каким то образом замапить на объект - или коллекцию ...Ярые противники Hiber'а так и не раскрыли тему мэппинга
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39257832
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanAtum13) Вызвать из java кода - и каким то образом замапить на объект - или коллекцию ...Ярые противники Hiber'а так и не раскрыли тему мэппинга

Я как раз не противник ... я ярый сторонник ... просто мне не очень нравится современный подход к решению ОРМ проблемы .

Я привел простой пример ...

Да я ищу Серебряную пулю - мне нужен компромисс ...


И Да - Писать лапшу на jdbc это оверхед ...

ДА мы пошли по верному пути - декларативный подход обернули метод @Transactional - введя Аспект - прокси и это правильно ...

код стал чище ...

но потом свернули куда то не туда и вместо одного кода из спагетти пишем другой из спегетти аннотаций - декларативный ...


вот еще раз пример :

http://www.thoughts-on-java.org/result-set-mapping-complex-mappings/

Код: java
1.
SELECT b.id, b.title, b.author_id, b.version, a.id as authorId, a.firstName, a.lastName, a.version as authorVersion FROM Book b JOIN Author a ON b.author_id = a.id



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
@SqlResultSetMapping(
        name = "BookAuthorMapping",
        entities = {
            @EntityResult(
                    entityClass = Book.class,
                    fields = {
                        @FieldResult(name = "id", column = "id"),
                        @FieldResult(name = "title", column = "title"),
                        @FieldResult(name = "author", column = "author_id"),
                        @FieldResult(name = "version", column = "version")}),
            @EntityResult(
                    entityClass = Author.class,
                    fields = {
                        @FieldResult(name = "id", column = "authorId"),
                        @FieldResult(name = "firstName", column = "firstName"),
                        @FieldResult(name = "lastName", column = "lastName"),



Код: java
1.
2.
3.
4.
5.
List<Object[]> results = this.em.createNativeQuery("SELECT b.id, b.title, b.author_id, b.version, a.id as authorId, a.firstName, a.lastName, a.version as authorVersion FROM Book b JOIN Author a ON b.author_id = a.id", "BookAuthorMapping").getResultList();

results.stream().forEach((record) -> {
    Book book = (Book)record[0];
    Author author = (Author)record[1];



+нужно добавить кеширование запросов , кеширование результатов , хинты итд ...

и где тут плюс ?

А да если делать через hql |jpql - Это будет не один запрос - а + n запросов для получения доп данных по модели ...

с которыми также еще нужно разбираться и автоматизировать ... и где плюсы? ткните носом?


А да - совсем забыл

Еще пара вопросов :

1)

удаление - через Хибер - чтобы просто выполнить delete - нужно создать темповую таблицу вставить туда id удаляемой записи - потом удалить ...

а если нужно удалить n записей ? как делать корректный батч на удаление ?


2)

обновить поле - нативно update .
а через орм - нужно вытащить весь объект ( + все коллекции у него если итд ) потом сохранить ...

3)
А да еще нельзя что то делать с самим объектом просто так ... и что то в нем менять ... нужно всегда его брать из базы ... все время помнить про жизненный цикл объекта (персист , аттац , детач, мердж, флеш ) - не слишком много ?
(помнить про корректность хешкода и иквался про иммутабельность в хешмапах итд ... )
...
Рейтинг: 0 / 0
jpql как вернуть min max в одном запросе ?
    #39258130
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Atum1,
все эти аннотации и запросы прямо в коде хороши для учебных целей и простейших случаев. Когда они разрастаются, гораздо удобнее работать с ними в ресурсных файлах. Ну и конечно, если есть возможность спускаться от jpa к hibernate/eclipselink/etc. Там гораздо больше возможностей.
Например, положительный ответ на доп.вопросы - в hibernate (hql) все crud-запросы работают
...
Рейтинг: 0 / 0
25 сообщений из 35, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / jpql как вернуть min max в одном запросе ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]