Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ДЗ по Hibernate #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 1 addition & 44 deletions hibernate-hw.iml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<module version="4">
<component name="FacetManager">
<facet type="jpa" name="JPA">
<configuration>
Expand All @@ -10,47 +10,4 @@
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_11">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

что-то лишнее в ПР

<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.postgresql:postgresql:42.2.5" level="project" />
<orderEntry type="library" name="Maven: org.hibernate:hibernate-core:5.4.0.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:javax.persistence-api:2.2" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.24.0-GA" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.9.5" level="project" />
<orderEntry type="library" name="Maven: antlr:antlr:2.7.7" level="project" />
<orderEntry type="library" name="Maven: org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:1.1.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss:jandex:2.0.5.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.4" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.dom4j:dom4j:2.1.1" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.common:hibernate-commons-annotations:5.1.0.Final" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jaxb:jaxb-runtime:2.3.1" level="project" />
<orderEntry type="library" name="Maven: org.glassfish.jaxb:txw2:2.3.1" level="project" />
<orderEntry type="library" name="Maven: com.sun.istack:istack-commons-runtime:3.0.7" level="project" />
<orderEntry type="library" name="Maven: org.jvnet.staxex:stax-ex:1.8" level="project" />
<orderEntry type="library" name="Maven: com.sun.xml.fastinfoset:FastInfoset:1.2.15" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.opentable.components:otj-pg-embedded:0.13.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apache.commons:commons-compress:1.18" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.tukaani:xz:1.5" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: commons-codec:commons-codec:1.11" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.github.spotbugs:spotbugs-annotations:3.1.7" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.slf4j:jcl-over-slf4j:1.7.25" level="project" />
</component>
</module>
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>11</source>
<target>11</target>
<source>15</source>
<target>15</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/ru/hh/school/dao/EmployerDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@ public EmployerDao(SessionFactory sessionFactory) {
}

/**
* TODO: здесь нужен метод, позволяющий сразу загрузить вакасии, связанные с работодателем и в некоторых случаях
* Здесь нужен метод, позволяющий сразу загрузить вакасии, связанные с работодателем и в некоторых случаях
* избежать org.hibernate.LazyInitializationException
* Также в запрос должен передаваться параметр employerId
* <p>
* https://vladmihalcea.com/the-best-way-to-handle-the-lazyinitializationexception/
*/
public Employer getEager(int employerId) {
return getSession()
.createQuery("from Employer employer", Employer.class)
.createQuery(
"""
FROM Employer employer LEFT JOIN FETCH employer.vacancies
WHERE employer.id = :id
""", Employer.class)
.setParameter("id", employerId)
.getSingleResult();
}

}
4 changes: 1 addition & 3 deletions src/main/java/ru/hh/school/dao/GenericDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import org.hibernate.SessionFactory;

import java.io.Serializable;
import java.util.Collection;
import java.util.Objects;

public class GenericDao {
private final SessionFactory sessionFactory;
Expand All @@ -25,7 +23,7 @@ public void save(Object object) {
if (object == null) {
return;
}
getSession().save(object);
getSession().saveOrUpdate(object);
}

protected Session getSession() {
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/ru/hh/school/dao/VacancyDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ public VacancyDao(SessionFactory sessionFactory) {
}

public StatisticsDto getSalaryStatistics(Area area){
// ToDo дополните запрос, чтобы возвращался ru.hh.school.employers.StatisticsDto
// Дополните запрос, чтобы возвращался ru.hh.school.employers.StatisticsDto
// https://vladmihalcea.com/the-best-way-to-map-a-projection-query-to-a-dto-with-jpa-and-hibernate/
return getSession().createQuery(
"SELECT count(v.id), min(v.compensationFrom), max(v.compensationTo) " +
"FROM Vacancy v WHERE v.area = :area", StatisticsDto.class)
"""
SELECT new ru.hh.school.employers.StatisticsDto(
count(v.id), min(v.compensationFrom), max(v.compensationTo))
FROM Vacancy v WHERE v.area = :area
""", StatisticsDto.class)
.setParameter("area", area)
.getSingleResult();
}
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/ru/hh/school/entity/Area.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
package ru.hh.school.entity;

//TODO: оформите entity
import javax.persistence.*;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

просто к сведению - мы не используем звёздочки, все пакеты импортим явно


//Оформите entity.
@Entity
@Table(name = "area")
public class Area {
@Id
@Column(name = "area_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@OneToOne(mappedBy = "area", cascade = CascadeType.ALL)
private Vacancy vacancy;

@Column(nullable = false)
private String name;

public Area() {}
public String getName() {
return name;
}
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/ru/hh/school/entity/Employer.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
package ru.hh.school.entity;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

//TODO: оформите entity
// Оформите entity
@Entity
@Table(name = "employer")
public class Employer {

@Id
@Column(name = "employer_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@Column(name = "company_name", nullable = false)
private String companyName;

// не используйте java.util.Date
// https://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/Hibernate_User_Guide.html#basic-datetime-java8
@Column(name = "creation_time")
private LocalDateTime creationTime;

@OneToMany(mappedBy = "employer", cascade = CascadeType.ALL)
private List<Vacancy> vacancies = new ArrayList<>();

@Column(name = "block_time")
private LocalDateTime blockTime;

public List<Vacancy> getVacancies() {
Expand Down
16 changes: 9 additions & 7 deletions src/main/java/ru/hh/school/entity/Resume.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
package ru.hh.school.entity;

import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.*;

//TODO: оформите entity
// Оформите entity
@Entity
@Table(name = "resume")
public class Resume {
// TODO: сделать так, чтобы id брался из sequence-а
// Сделать так, чтобы id брался из sequence-а
// таким образом, мы сможем отправлять в бд запросы батчами.
// нужно учитывать, что описание sequence при создании таблицы также должно соответствовать
// хиберовской сущности (см. create_resume.sql)
//
// Подробнее:
// https://vladmihalcea.com/how-to-batch-insert-and-update-statements-with-hibernate/
// https://vladmihalcea.com /how-to-batch-insert-and-update-statements-with-hibernate/
// https://vladmihalcea.com/from-jpa-to-hibernates-legacy-and-enhanced-identifier-generators/

@Id
@GeneratedValue(/* здесь место для вашего кода */)
@GeneratedValue(generator = "resume_id_seq", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(name = "resume_id_seq", allocationSize = 10)
private Integer id;

private String description;

Resume() {}
public Resume() {}

public Resume(String description) {
this.description = description;
Expand Down
27 changes: 17 additions & 10 deletions src/main/java/ru/hh/school/entity/Vacancy.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,45 @@
package ru.hh.school.entity;

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.Table;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.Objects;

//TODO: оформите entity
// Оформите entity
@Entity
@Table(name = "vacancy")
public class Vacancy {

@Id
@Column(name = "vacancy_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "employer_id", nullable = false)
private Employer employer;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "area_id")
private Area area;

@Column(nullable = false)
private String title;

private String description;

@Column(name = "compensation_from")
private Integer compensationFrom;

@Column(name = "compensation_to")
private Integer compensationTo;

@Column(name = "compensation_gross")
private Boolean compensationGross;

@Column(name = "creation_time")
private LocalDateTime creationTime;

@Column(name = "archiving_time")
private LocalDateTime archivingTime;

public Vacancy() {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/ru/hh/school/service/EmployerService.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,17 @@ public void blockIfEmployerUseBadWords(int employerId) {
return;
}

// TODO: сделать сохранение состояния работодателя и его вакансий
// Сделать сохранение состояния работодателя и его вакансий
// сейчас Employer в detached состоянии, т.к. сессия закрылась.
// это нужно учитывать при последующей работе с таковым
// про состояния: https://vladmihalcea.com/a-beginners-guide-to-jpa-hibernate-entity-state-transitions/
// про возврат в managed состояние: https://vladmihalcea.com/jpa-persist-and-merge


transactionHelper.inTransaction(() -> {
employer.setBlockTime(LocalDateTime.now());
employer.getVacancies().forEach(v -> v.setArchivingTime(LocalDateTime.now()));
genericDao.save(employer);
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/java/ru/hh/school/batching/BatchingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public void clearTable() {
}

/**
* ToDo доконфигурируйте ru.hh.school.batching.Resume
* Доконфигурируйте ru.hh.school.batching.Resume
*
* @see scripts/create_resume.sql
* и hibernate.properties (раздел batch processing)
Expand Down