HabrÃ©ã®æåã®èšäºã§ã¯ãã»ãã·ã§ã³ãšãã©ã³ã¶ã¯ã·ã§ã³ã«é¢ããHibernateãšã®é£æºã«é¢ããããã€ãã®èããšæèŠãå
±æããããšæããŸãã ãã®ãããã¯ã®éçºã®æåã«çããããã€ãã®ãã¥ã¢ã³ã¹ã«çŠç¹ãåœãŠãŸããã ãžã¥ãã¢ããã°ã©ããŒèªèº«ãHibernateãåžžæäœ¿çšããŠããªãã£ãã®ã§ããšã©ãŒãçºçããå¯èœæ§ããããŸãããããã«æ°ã¥ããå Žåã¯ãä¿®æ£ã«æè¬ããŸãã
Hibernateã©ã€ãã©ãªã¯ãæãäžè¬çãªORMã©ã€ãã©ãªã§ãããJava Persistence APIã®å®è£
ã§ãã å€ãã®å Žåãéåžžã®Javaã¢ããªã±ãŒã·ã§ã³ãç¹ã«JBossã¢ããªã±ãŒã·ã§ã³ãµãŒããŒïŒããã³ãã®åå«ã®WildFlyïŒã®ãµãŒãã¬ããã³ã³ãããŒã§ORMãããã€ããŒãšããŠäœ¿çšãããŸãã
å§ããŸãããã
1ïŒã ãšã³ãã£ãã£ãªããžã§ã¯ã
ãŠãŒã¶ãŒãšåœŒã®ã¿ã¹ã¯ã®2ã€ã®ãšã³ãã£ãã£ãèããŸãã
CREATE TABLE "user" ( user_id serial NOT NULL, login character varying(10), password character varying(10), role integer, name character varying(20) NOT NULL, CONSTRAINT user_pkey PRIMARY KEY (user_id) ) CREATE TABLE task ( task_id serial NOT NULL, user_id bigint, task_date date, name character varying(20), definition character varying(200), CONSTRAINT tasks_pkey PRIMARY KEY (task_id), CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES "user" (user_id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION )
次ã«ããããã®ããŒãã«ã®ãšã³ãã£ãã£ã¯ã©ã¹ã瀺ããŸãã
@Entity @Table(name = "user", schema = "public") public class User { private Long userId; private String name; private String login; private String password; private Integer role; private List<Task> tasks; @Id @SequenceGenerator(name = "user_seq", sequenceName = "user_user_id_seq", allocationSize = 0) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq") @Column(name = "user_id") public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL) public List<Tasks> getTasks() { return tasks; } public void setTasks(List<Tasks> tasks) { this.tasks = tasks; } @Column(name = "name") public String getName() { return name; } public void setName(String name) { this.name = name; } @Column(name = "login") public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } @Column(name = "password") public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } @Entity @Table(name = "task", schema = "public") public class Task { private Long taskId; private User user; private Date taskDate; private String name; private String definition; private Priority priority; private Type type; @Id @SequenceGenerator(name = "tasks_seq", sequenceName = "tasks_task_id_seq", allocationSize = 0) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tasks_seq") @Column(name = "task_id", unique = true, nullable = false) public Long getTaskId() { return taskId; } public void setTaskId(Long taskId) { this.taskId = taskId; } @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "user_id") public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Column(name = "task_date") public Date getTaskDate() { return taskDate; } public void setTaskDate(Date taskDate) { this.taskDate = taskDate; } @Column(name = "name") public String getName() { return name; } public void setName(String name) { this.name = name; } @Column(name = "definition") public String getDefinition() { return definition; } public void setDefinition(String definition) { this.definition = definition; } }
JPAã¢ãããŒã·ã§ã³ã«ã€ããŠã¯
ãã¡ããã芧ãã ãã ã
2ïŒã ã»ãã·ã§ã³ã€ã³ã¿ãŒãã§ãŒã¹
Hibernateã§ã¯ãããŒã¿ããŒã¹ã®æäœã¯
org.hibernate.Sessionåã®ãªããžã§ã¯ããä»ããŠè¡ãããŸãã
ããã¥ã¡ã³ãããã®æç²ïŒ
Javaã¢ããªã±ãŒã·ã§ã³ãšHibernateã®éã®ã¡ã€ã³ã©ã³ã¿ã€ã ã€ã³ã¿ãŒãã§ãŒã¹ã ããã¯ãæ°žç¶åãµãŒãã¹ã®æŠå¿µãæœè±¡åããäžå¿çãªAPIã¯ã©ã¹ã§ãã
ã»ãã·ã§ã³ã®ã©ã€ããµã€ã¯ã«ã¯ãè«çãã©ã³ã¶ã¯ã·ã§ã³ã®éå§ãšçµäºã«ãã£ãŠå¶éãããŸãã ïŒé·ããã©ã³ã¶ã¯ã·ã§ã³ã¯è€æ°ã®ããŒã¿ããŒã¹ãã©ã³ã¶ã¯ã·ã§ã³ã«ãŸãããããšããããŸããïŒ
ã»ãã·ã§ã³ã®äž»ãªæ©èœã¯ããããããããšã³ãã£ãã£ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã®äœæãèªã¿åããå逿äœãæäŸããããšã§ãã
org.hibernate.Sessionã€ã³ã¿ãŒãã§ãŒã¹ã¯ãã¢ããªã±ãŒã·ã§ã³ãšHibernateã®éã®ããªããžã§ãã ã»ãã·ã§ã³ã䜿çšããŠã
ãšã³ãã£ãã£ãªããžã§ã¯ãã䜿çšãããã¹ãŠã®CRUDæäœãå®è¡ãããŸãã
Sessionåã®ãªããžã§ã¯ãã¯ã
org.hibernate.SessionFactoryåã®ã€ã³ã¹ã¿ã³ã¹ããååŸãããŸãããã®ã€ã³ã¹ã¿ã³ã¹ã¯ãã¢ããªã±ãŒã·ã§ã³ã«
ã·ã³ã°ã«ãã³ãšããŠååšããå¿
èŠããããŸãã
3ïŒã ãªããžã§ã¯ãã®ç¶æ
ãšã³ãã£ãã£ãªããžã§ã¯ãã¯ã次ã®3ã€ã®ç¶æ
ïŒã¹ããŒã¿ã¹ïŒã®ããããã«ãªããŸãã
- äžæçãªãªããžã§ã¯ã ã ãã®ã¹ããŒã¿ã¹ã®ãªããžã§ã¯ãã¯ããšã³ãã£ãã£ã¯ã©ã¹ã®å¡ãã€ã¶ãããã€ã³ã¹ã¿ã³ã¹ã§ãã ããŒã¿ããŒã¹ã«ä¿åã§ããŸãã ã»ãã·ã§ã³ã«æ¥ç¶ãããŠããŸããã Idãã£ãŒã«ãã«ã¯å
¥åããªãã§ãã ãããããããªããšããªããžã§ã¯ãã®ã¹ããŒã¿ã¹ããã¿ãããããŸãã
- æ°žç¶ãªããžã§ã¯ã ã ãã®ã¹ããŒã¿ã¹ã®ãªããžã§ã¯ãã¯ãç¹å®ã®ã»ãã·ã§ã³ã«ã¢ã¿ãããããããããä¿åããããšã³ãã£ãã£ã§ãã ãã®ã¹ããŒã¿ã¹ã§ã®ã¿ããªããžã§ã¯ãã¯ããŒã¿ããŒã¹ãšå¯Ÿè©±ããŸãã ãã©ã³ã¶ã¯ã·ã§ã³ã§ãã®ã¿ã€ãã®ãªããžã§ã¯ããæäœããå Žåããªããžã§ã¯ãã«å¯Ÿãããã¹ãŠã®å€æŽã¯ããŒã¿ããŒã¹ã«èšé²ãããŸãã
- åé¢ãªããžã§ã¯ã ã ãã®ã¹ããŒã¿ã¹ã®ãªããžã§ã¯ãã¯ãã»ãã·ã§ã³ããåæããããªããžã§ã¯ãã§ãããããŒã¿ããŒã¹ã«ååšããå Žåãšååšããªãå ŽåããããŸãã
ãšã³ãã£ãã£ãªããžã§ã¯ãã¯ãããã¹ããŒã¿ã¹ããå¥ã®ã¹ããŒã¿ã¹ã«è»¢éã§ããŸãã ãããè¡ãã«ã¯ã次ã®ã¡ãœããã
Sessionã€ã³ã¿ãŒãã§ãŒã¹ã«ååšããŸãã
- persistïŒãªããžã§ã¯ãïŒ -ãªããžã§ã¯ããtransientããpersistentã«å€æããŸããã€ãŸããã»ãã·ã§ã³ã«ã¢ã¿ããããŠããŒã¿ããŒã¹ã«ä¿åããŸãã ãã ãããªããžã§ã¯ãã®Idãã£ãŒã«ãã«å€ãå²ãåœãŠããšã PersistentObjectExceptionãçºçããŸããHibernateã¯ã ãã¿ããããããªããžã§ã¯ããã€ãŸãããŒã¿ããŒã¹ã«ååšãããšèŠãªããŸãã ä¿åæã«ã persistïŒïŒã¡ãœããã¯selectãäœæããã«ããã«æ¿å
¥ãå®è¡ããŸã ã
- mergeïŒãªããžã§ã¯ãïŒ -ãªããžã§ã¯ããäžæçãŸãã¯åé¢ããããªããžã§ã¯ãããæ°žç¶ çãªãªããžã§ã¯ãã«å€æããŸãã transientã®å Žåã persistïŒïŒ ïŒèšå®ãããŠããŠããªããžã§ã¯ãã®æ°ããIDãçæããïŒãšåæ§ã«åäœãã detachedã®å ŽåãããŒã¿ããŒã¹ãããªããžã§ã¯ããããŒãããã»ãã·ã§ã³ã«ã¢ã¿ããããä¿åæã«æŽæ°ãå®è¡ããŸã
- replicateïŒObjectãReplicationModeïŒ -ãªããžã§ã¯ãããã¿ããããæ°žç¶ã«å€æããŸããããªããžã§ã¯ãã«ã¯äºåã«Idãèšå®ããå¿
èŠããããŸãã ãã®ã¡ãœããã¯ãç¹å®ã®IDãæã€ãªããžã§ã¯ããããŒã¿ããŒã¹ã«ä¿åããããã«èšèšãããŠããŸããã æ°žç¶åïŒïŒããã³ããŒãžïŒïŒã¯èš±å¯ããŸããã ãã®IDãæã€ãªããžã§ã¯ããããŒã¿ããŒã¹ã«ãã§ã«ååšããå Žåãåäœã¯org.hibernate.ReplicationModeåæããã®èŠåã«åŸã£ãŠæ±ºå®ãããŸãã
ReplicationMode.IGNORE-ããŒã¿ããŒã¹ã®å€æŽã¯ãããŸããã
ReplicationMode.OVERWRITE-ãªããžã§ã¯ãã¯ãæ¢åã®ãªããžã§ã¯ãã§ã¯ãªãããŒã¿ããŒã¹ã«ä¿åãããŸãã
ReplicationMode.LATEST_VERSION-ææ°ããŒãžã§ã³ã®ãªããžã§ã¯ããããŒã¿ããŒã¹ã«ä¿åãããŸãã
ReplicationMode.EXCEPTION-äŸå€ãã¹ããŒããŸãã - deleteïŒãªããžã§ã¯ãïŒ -ããŒã¿ããŒã¹ãããªããžã§ã¯ããåé€ããŸããã€ãŸãã persistentãtransientã«å€æããŸãã ãªããžã§ã¯ãã¯ã©ã®ãããªç¶æ
ã§ãããŸããŸãããäž»ãªããšã¯ã IDãèšå®ãããŠããããšã§ãã
- saveïŒãªããžã§ã¯ãïŒ -ãªããžã§ã¯ããããŒã¿ããŒã¹ã«ä¿åããã€ã³ã¹ããŒã«ãããŠããŠãæ°ããIdãçæããŸãã ãªããžã§ã¯ãã¯äžæçãŸãã¯åãé¢ãããå¯èœæ§ããããŸã
- updateïŒãªããžã§ã¯ãïŒ -ããŒã¿ããŒã¹å
ã®ãªããžã§ã¯ããæŽæ°ãã æ°žç¶ ãªããžã§ã¯ãã«å€æããŸãïŒ åé¢ç¶æ
ã®ãªããžã§ã¯ã ïŒ
- saveOrUpdateïŒãªããžã§ã¯ãïŒ-saveïŒ ïŒãŸãã¯updateïŒïŒãåŒã³åºããŸã
- refreshïŒãªããžã§ã¯ãïŒ -ããŒã¿ããŒã¹ã«å¯ŸããŠselectãå®è¡ãã æ°žç¶ãªããžã§ã¯ãã«å€æããããšã«ããã ãã¿ããããããªããžã§ã¯ããæŽæ°ãã
- getïŒObject.classãidïŒ - æ°žç¶ç¶æ
ã®ç¹å®ã®IDãæã€ããŒã¿ããŒã¹ãããšã³ãã£ãã£ãŒã¯ã©ã¹ã®ãªããžã§ã¯ããååŸããŸã
Sessionãªããžã§ã¯ãã¯ãããŒãããããªããžã§ã¯ãããã£ãã·ã¥ããŸãã ããŒã¿ããŒã¹ãããªããžã§ã¯ããããŒããããšãããã£ãã·ã¥ãæåã«ãã§ãã¯ãããŸãã ãã£ãã·ã¥ãããªããžã§ã¯ããåé€ããŠã»ãã·ã§ã³ããåæããã«ã¯ã
session.evictïŒObjectïŒã䜿çšããŸãã
session.clearïŒïŒã¡ãœããã¯ãã»ãã·ã§ã³å
ã®ãã¹ãŠã®ãªããžã§ã¯ãã«
evictïŒïŒãé©çšããŸãã
ããã§ã
ãšã³ãã£ãã£ã¯ã©ã¹ã®ã¢ãããŒã·ã§ã³
@OneToManyããã³
@ManyToOneãèŠãŠã¿ãŸãããã
@OneToManyã®
ãã§ãããã©ã¡ãŒã¿ãŒã¯ãåãªããžã§ã¯ãããã€èªã¿èŸŒã
ãã瀺ããŸãã
javax.persistence.FetchTypeåæã§æå®ããã2ã€ã®å€ã®ãããããæã€ããšãã§ããŸãã
FetchType.EAGER-芪ãªããžã§ã¯ããããŒããããšãã«ãåãªããžã§ã¯ãã®ã³ã¬ã¯ã·ã§ã³ãããã«ããŒãããŸãã
FetchType.LAZY-æåã®ã¢ã¯ã»ã¹æã«åãªããžã§ã¯ãã®ã³ã¬ã¯ã·ã§ã³ãããŒãããŸãïŒ
getãåŒã³åºã
ãŸã ïŒ-ããããé
å»¶ããŒãã
ã«ã¹ã±ãŒããã©ã¡ãŒã¿ãŒã¯ã
ã»ãã·ã§ã³ã€ã³ã¿ãŒãã§ãŒã¹ã®ã©ã®ã¡ãœãããé¢é£ãããšã³ãã£ãã£ã«ã«ã¹ã±ãŒãããããã瀺ããŸãã ããšãã°ã
ã¿ã¹ã¯ã³ã¬ã¯ã·ã§ã³ã®
Userãšã³ãã£ãã£ã¯ã©ã¹ã§ã次ãæå®ããŸãã
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = {CascadeType.PERSIST, CascadeType.MERGE}) public List<Tasks> getTasks() { return tasks; } public void setTasks(List<Tasks> tasks) { this.tasks = tasks; }
次ã«ã
session.persistïŒãŠãŒã¶ãŒïŒãŸãã¯
session.mergeïŒãŠãŒã¶ãŒïŒãå®è¡ããããšã
ã¿ã¹ã¯ããã®ãã¹ãŠã®ãªããžã§ã¯ãã«
æ°žç¶åãŸãã¯
ããŒãžæäœãé©çšãããŸãã
javax.persistence.CascadeTypeåæã®æ®ãã®æäœã«ã€ããŠãåæ§ã§ãã
CascadeType.ALLã¯ãåæããã®ãã¹ãŠã®æäœãé©çšããŸãã ããŒã¿ããŒã¹ããäžèŠãªé¢é£ãšã³ãã£ãã£ãªããžã§ã¯ãã®æãããŒãããªãããã«ã
CascadeTypeãæ£ããæ§æããå¿
èŠããããŸãã
4ïŒã ããŒã¿ããŒã¹ãããªããžã§ã¯ããæœåºãã
以äžã«ç°¡åãªäŸã瀺ããŸãã
@Autowired private SessionFactory sessionFactory public void getTasks(Long userId) { ... Session session = sessionFactory.openSession(); User user = (User) session.load(User.class, userId); Session session = sessionFactory.openSession(); List<Task> tasksList = user.getTasks(); ... }
session.getïŒïŒã¡ãœããã®ä»£ããã«ã
session.loadïŒïŒã䜿çšã§ããŸãã
session.loadïŒïŒã¡ãœããã¯ããããã
proxy-objectãè¿ã
ãŸã ã
ãããã·ãªããžã§ã¯ãã¯ãããŒã¿ããŒã¹å
ã®å®éã®ãªããžã§ã¯ããšããåãã§ããäžéãªããžã§ã¯ãã§ãã ãšã³ãã£ãã£ãªããžã§ã¯ãã®æ©èœãæ¡åŒµããŸãã
ãããã·ãªããžã§ã¯ããšã®çžäºäœçšã¯ããšã³ãã£ãã£ãªããžã§ã¯ããšã®çžäºäœçšã«å®å
šã«äŒŒãŠããŸãã
ãããã·ãªããžã§ã¯ãã¯ã
ãããã·ãªããžã§ã¯ããäœæãããšãã«ããŒã¿ããŒã¹ã¯ãšãªãå®è¡ãããªããšããç¹ã§ãšã³ãã£ãã£
ãªããžã§ã¯ããšã¯ç°ãªããŸããã€ãŸããHibernateã¯ãã®
IDãæã€ãªããžã§ã¯ããããŒã¿ããŒã¹ã«ååšãããšåçŽã«ä¿¡ããŠããŸãã ãã ãã
proxy-objectã®æåã®
getãŸãã¯
setåŒã³åºãã¯ããã«
éžæèŠæ±ãéå§ããæå®ããã
IDãæã€ãªããžã§ã¯ããããŒã¿ããŒã¹ã«ãªãå Žåã
ObjectNotFoundExceptionãååŸã
ãŸã ã
ãããã·ãªããžã§ã¯ãã®äž»ãªç®çã¯ãé
å»¶ããŒããå®è£
ããããšã§ãã
FetchType.LAZY㯠tasksã® Userã¯ã©ã¹ã§èšå®ãããŠããããã
user.getTasksïŒïŒåŒã³åºãã¯ããŒã¿ããŒã¹ããã®ãŠãŒã¶ãŒã¿ã¹ã¯ã®ããŒããéå§ããŸãã
LazyInitializationException
FetchType.LAZYãã©ã¡ãŒã¿ãŒã«ã¯æ³šæ
ããå¿
èŠããããŸãã é¢é£ãããšã³ãã£ãã£ãããŒããããšãã«ã
LazyInitializationExceptionããã£ãããã
å ŽåããããŸãã äžèšã®ã³ãŒãã§ã¯ã
user.getTasksïŒïŒãåŒã³åºããšã
ã ãŠãŒã¶ãŒã¯
æ°žç¶ã¹ããŒã¿ã¹ãŸãã¯
ãããã·ã¹ããŒã¿ã¹ã§ããå¿
èŠããããŸãã
ãŸãã
LazyInitializationExceptionã«ãããã³ãŒããè¥å¹²å€æŽãããå ŽåããããŸãã
public List<Task> getTasks(Long userId) { ... Session session = sessionFactory.openSession(); User user = (User) session.load(User.class, userId); List<Task> tasksList = user.getTasks(); session.close(); return tasksList; }
ããã§ã¯ãã¹ãŠãçè«çã«çå®ã§ãã ãã ãã
tasksListã«ã¢ã¯ã»ã¹ããããšãããšã
LazyInitializationExceptionãçºçããå¯èœ
æ§ããã
ãŸã ã ãããããããã¬ãŒã§ã¯ããã®ã³ãŒãã¯æ£ããæ©èœããŸãã ãªãã§ïŒ
user.getTasksïŒïŒã¯ã³ã¬ã¯ã·ã§ã³ãžã®åç
§ã®ã¿ãè¿ãããã³ã¬ã¯ã·ã§ã³ã®ããŒããåŸ
æ©ããªãããã§ãã ããŒã¿ã®èªã¿èŸŒã¿ãåŸ
ããã«ãã»ãã·ã§ã³ãéããŸããã åºåã¯ãã©ã³ã¶ã¯ã·ã§ã³ã§å®è¡ãããŸããã€ãŸãïŒ
public List<Task> getTasks(Long userId) { ... User user = (User) session.load(User.class, userId); Session session = sessionFactory.openSession(); session.beginTransaction(); List<Task> tasksList = user.getTasks(); session.getTransaction().commit(); return tasksList; }
æ¡ä»¶ä»ãéžæ
次ã«ãæ¡ä»¶ä»ãã®ããŒã¿ãµã³ããªã³ã°ã®ç°¡åãªäŸãããã€ã瀺ããŸãã ãã®ãããã¿ã€ã
org.hibernate.Criteriaã®ãªããžã§ã¯ããHibernateã§äœ¿çšãããŸãã
public List<Task> getUser(String login) { ... Session session = sessionFactory.openSession(); Criteria userCriteria = session.createCriteria(User.class); userCriteria.add(Restrictions.eq("login", login)); user = (User) userCriteria.uniqueResult(); session.close(); ... }
ããã§
ãlogin = 'login'ã®ãŠãŒã¶ãŒããselect *ãå®è¡ããŠããããšãæããã§ãã
addã¡ãœããã§ã¯ãç¹å®ã®éžæåºæºã衚ãã¿ã€ã
Criterionã®ãªããžã§ã¯ããæž¡ããŸãã
org.hibernate.criterion.Restrictionsã¯ã©ã¹ã¯ãããŸããŸãªçš®é¡ã®åºæºãæäŸããŸãã ããã°ã€ã³ããã©ã¡ãŒã¿ã¯ãããŒã¿ããŒã¹ããŒãã«ã®ãã£ãŒã«ãã§ã¯ãªãããšã³ãã£ãã£ã¯ã©ã¹ã®ããããã£ã®ååã瀺ããŸãã
ããã«ããã€ãã®äŸã瀺ããŸãã
aïŒã
public List<Task> getTasksByName(String name) { ... session = sessionFactory.openSession(); Criteria criteria = session.createCriteria(Task.class); List<Task> tasks = criteria.add(Restrictions.like("name", name, MatchMode.ANYWHERE)).list(); ... }
ããã§ã¯ã
Taskãšã³ãã£ãã£ã¯ã©ã¹ã®
nameããããã£ã®ã³ã³ãã³ããéžæããŸãã
MatchMode.ANYWHEREã¯ã
ãnameãããããã£å
ã®ä»»æã®å Žæã§éšåæåå
åãæ€çŽ¢ããå¿
èŠãããããšãæå³ããŸãã
bïŒ
ãããŠãããã§ã¯ããŒãã«ã®20çªç®ã®æ°å€ããå§ããŠ50è¡ãååŸããŸãã
public List<Task> getTasks() { ... Session session = sessionFactory.openSession(); Criteria criteria = session.createCriteria(Task.class); List<Task> tasks = criteria.setFirstResult(20).setMaxResults(50).list(); ... }
5ïŒã ãªããžã§ã¯ããä¿åãã
ãšã³ãã£ãã£ãªããžã§ã¯ããããŒã¿ããŒã¹ã«ä¿åããããã€ãã®æ¹æ³ãèŠãŠã¿ãŸãããã
aïŒã
äžæãªããžã§ã¯ããäœæããããŒã¿ããŒã¹ã«ä¿åããŸãã
@Autowired private UserDao userDao; @Autowired private SessionFactory sessionFactory; public void saveUser(String login) { User user = userDao.getUserByLogin(login); Session session = sessionFactory.openSession(); session.openTransaction(); Task task = new Task(); task.setName(" 1"); task.setDefinition(" 1"); task.setTaskDate(new Date()); task.setUser(user); session.saveOrUpdate(task); session.flush(); session.getTransaction().commit(); return task.getTaskId(); }
ããã€ãã®ãã¥ã¢ã³ã¹ã«æ³šæããŠãã ããã ãŸããããŒã¿ããŒã¹ãžã®ä¿åã¯ãã©ã³ã¶ã¯ã·ã§ã³ã®äžéšãšããŠã®ã¿å®è¡ã§ããŸãã
session.openTransactionïŒïŒãåŒã³åºããšããã®ã»ãã·ã§ã³ã®æ°ãããã©ã³ã¶ã¯ã·ã§ã³ãéãã
session.getTransactionïŒïŒãCommitïŒïŒãå®è¡ããŸãã æ¬¡ã«ã
task.setUserïŒuserïŒã¡ãœããã§ã
ãŠãŒã¶ãŒã
åé¢ç¶æ
ã§æž¡ã
ãŸã ã
æ°žç¶çãªã¹ããŒã¿ã¹ã§è»¢éããããšãã§ããŸãã
ãã®ã³ãŒãã¯ïŒ
ãŠãŒã¶ãŒã®åä¿¡ãšã¯å¥ã«ïŒ2ã€ã®ãªã¯ãšã¹ããå®è¡ã
ãŸã-nextvalïŒ 'task_task_id_seq'ïŒã
éžæ ããã¿ã¹ã¯ã«æ¿å
¥ããŸã...saveOrUpdateïŒïŒã®ä»£ããã«ã
saveïŒïŒ ã
persistïŒïŒ ã
mergeïŒïŒãå®è¡ã§ããŸã-2ã€ã®ã¯ãšãªããããŸãã
session.flushïŒïŒåŒã³åºãã¯ãã¹ãŠã®å€æŽãããŒã¿ããŒã¹ã«é©çšããŸãããæ£çŽãªãšããã
commitïŒïŒèªäœã¯
flushïŒïŒãåŒã³åºããŸã§ããŒã¿ããŒã¹ã«äœãä¿åãããªãããããã®åŒã³åºãã¯ããã§ã¯åœ¹ã«ç«ã¡ãŸããã
ããŒã¿ããŒã¹ããããŒãããã
æ°žç¶ ãªããžã§ã¯ããŸãã¯
ãããã·ãªããžã§ã¯ãã¹ããŒã¿ã¹ãªããžã§ã¯ãã®ãã©ã³ã¶ã¯ã·ã§ã³å
ã§äœãã倿Žãããšã
æŽæ°ãªã¯ãšã¹ããå®è¡ãããããšã«æ³šæããŠãã ããã
ã¿ã¹ã¯ãæ°ãã
ãŠãŒã¶ãŒãåç
§ããå¿
èŠãããå Žåã¯ã次ãå®è¡ããŸãã
User user = new User();
泚ïŒ
ãŠãŒã¶ãŒãã£ãŒã«ãã®
Taskã¯ã©ã¹ã§ã¯ã
CascadeType.PERSIST ã
CascadeType.MERGEããŸãã¯
CascadeType.ALLãèšå®ããå¿
èŠããããŸãã
ããŒã¿ããŒã¹ã«ååšãããŠãŒã¶ãŒã§ãã
userIdãæå
ã«ããå ŽåãããŒã¿ããŒã¹ãã
Userãªããžã§ã¯ããããŒãããå¿
èŠã¯ãªãã远å ã®
selectãäœæã
ãŸã ã ãŠãŒã¶ãŒIDã
Taskã¯ã©ã¹ã®ããããã£ã«çŽæ¥å²ãåœãŠãããšã¯ã§ããªãããã
userIdã®ã¿ãå
¥åããŠ
Userã¯ã©ã¹ã®ãªããžã§ã¯ããäœæããå¿
èŠããããŸãã åœç¶ãããã¯
transient-objectã«ã§ããªããããããã§ã¯æ¢ç¥ã®
ãããã·ãªããžã§ã¯ãã䜿çšããå¿
èŠããããŸãã
public void saveTask(Long userId, Task task) ... task.setUser((User) session.load(User.class, userId));
bïŒ ãªããžã§ã¯ããåãªããžã§ã¯ãã®ã³ã¬ã¯ã·ã§ã³ã«è¿œå ããŸãã
public Long saveUser(String login) { Session session = sessionFactory.openSession(); session.openTransaction(); user = (User) session.load(User.class, userId); Task task = new Task(); task.setName(""); task.setUser(user); user.getTasks().add(task); session.getTransaction().commit(); return user.getUserId(); }
Userã§ã¯ã tasksããããã£ã«
CascadeType.ALLãå¿
èŠã§ãã
CascadeType.MERGEãã€ã³ã¹ããŒã«ãããŠããå Žåã
user.getTasksïŒïŒã®åŸã«
远å ïŒtaskïŒ session.mergeïŒuserïŒãå®è¡ã
ãŸã ã ãã®ã³ãŒãã¯3ã€ã®ã¯ãšãªãå®è¡ã
ãŸã -
ãŠãŒã¶ãŒãã*ã éžæããnextvalïŒ 'task_task_id_seq'ïŒã
éžæ ããŠã¿ã¹ã¯ã«æ¿å
¥ããŸã ...
6ïŒã ãªããžã§ã¯ããåé€ãã
aïŒã
transient-objectãäœæããããšã§åé€ã§ã
ãŸã ïŒ
public void deleteTask(Long taskId) { Session session = sessionFactory.openSession(); session.openTransaction(); Tasks task = new Tasks(); task.setTaskId(taskId); session.delete(task); session.getTransaction().commit(); }
ãã®ã³ãŒãã¯
ã¿ã¹ã¯ã®ã¿ãåé€ã
ãŸã ã ãã ãã
ã¿ã¹ã¯ãã¿ã€ã
proxy ã
persistentãŸãã¯
detachedã®ãªããžã§ã¯ãã§ããã
CascadeType.REMOVEã
ãŠãŒã¶ãŒãã£ãŒã«ãã®
Taskã¯ã©ã¹ã§åäœãã
å Žå ãé¢é£ãã
ãŠãŒã¶ãŒãããŒã¿ããŒã¹ããåé€ãããŸãã ãŠãŒã¶ãŒãåé€ããå¿
èŠããªãå Žåã¯ãã©ãããŸããïŒ ããã
task.setUserïŒnullïŒbïŒ ãã®æ¹æ³ã§åé€ã§ããŸãïŒ
public void deleteTask(Long userId, Long taskId) { User user = (User) session.load(User.class, userId); user.getTasks().removeIf((Task task) -> { if (task.getTaskId() == taskId) { task.setUser(null); return true; } else return false; }); }
ãã®ã³ãŒãã¯ã
ã¿ã¹ã¯ãš
ãŠãŒã¶ãŒéã®æ¥ç¶ãåã«åé€ã
ãŸã ã ããã§ã¯ãnewfangled
lambdaåŒãé©çšããŸãã
ã¿ã¹ã¯ãªããžã§ã¯ãã¯ã1ã€ã®æ¡ä»¶äžã§ããŒã¿ããŒã¹ããåé€ãããŸã
-Userãšã³ãã£ãã£ã¯ã©ã¹ã§äœãã倿Žããå ŽåïŒ
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) public List<Tasks> getTasks() { return tasks; } public void setTasks(List<Tasks> tasks) { this.tasks = tasks; }
orphanRemoval = trueãã©ã¡ãŒã¿ãŒã¯ã
ãŠãŒã¶ãŒãžã®ãªã³ã¯ãæããªããã¹ãŠã®
Taskãªããžã§ã¯ããããŒã¿ããŒã¹ããåé€ããããšãæå®ããŸãã
7ïŒã 宣èšçãªãã©ã³ã¶ã¯ã·ã§ã³ç®¡ç
宣èšçãªãã©ã³ã¶ã¯ã·ã§ã³ç®¡çã®ããã«ã
Spring Frameworkã䜿çšã
ãŸã ã ãã©ã³ã¶ã¯ã·ã§ã³ç®¡çã¯ããã©ã³ã¶ã¯ã·ã§ã³ãããŒãžã£ãä»ããŠè¡ãããŸãã
session.openTransactionïŒïŒããã³
session.commitïŒïŒãåŒã³åºã代ããã«ã
@ Transactionalã¢ãããŒã·ã§ã³ã
䜿çšãããŸãã ã¢ããªã±ãŒã·ã§ã³æ§æã«ã¯æ¬¡ã®ãã®ãå¿
èŠã§ãã
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/>
ããã§ã¯ã
sessionFactory Beanã
ãã€ã³ãããã
transactionManager Beanãå®çŸ©ããŸããã
HibernateTransactionManagerã¯ã©ã¹ã¯ãHibernateã©ã€ãã©ãªã®
SessionFactoryçšã®å
±éã®
org.springframework.transaction.PlatformTransactionManagerã€ã³ã¿ãŒãã§ãŒã¹ã®å®è£
ã§ãã
ã¢ãããŒã·ã§ã³é§ååã¯ããã©ã³ã¶ã¯ã·ã§ã³ãããŒãžã£ã«
@Transactionalã¢ãããŒã·ã§ã³ãåŠçããããã«æç€ºã
ãŸã ã
-Chatterã¯ç¡äŸ¡å€ã§ãã ã³ãŒããèŠããŠãã ããã
ïŒã©ã€ãã¹ã»ããŒãã«ãºïŒ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {ObjectNotFoundException.class, ConstraintViolationException.class}) public Long saveTask(Long userId) { Session session = sessionFactory.getCurrentSession(); Tasks task = new Tasks(); task.setName(" 1"); task.setDefinition(" 1"); task.setTaskDate(new Date()); task.setUser((User) session.load(User.class, userId)); session.saveOrUpdate(task); return task.getTaskId(); }
@Transactional泚éã¯ãã¡ãœããããã©ã³ã¶ã¯ã·ã§ã³ã§å®è¡ããå¿
èŠãããããšã瀺ã
ãŸã ã ãã©ã³ã¶ã¯ã·ã§ã³ãããŒãžã£ãŒã¯æ°ãããã©ã³ã¶ã¯ã·ã§ã³ãéãããã®
ã»ãã·ã§ã³ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãããã®ã€ã³ã¹ã¿ã³ã¹ã¯ã
sessionFactory.getCurrentSessionïŒïŒãä»ããŠå©çšã§ããŸãã
Sessionã€ã³ã¹ã¿ã³ã¹ã¯ã¹ã¬ãã倿°ïŒThreadLocalïŒã§ããããããã®ã¢ãããŒã·ã§ã³ãæã€ã¡ãœããã§åŒã³åºããããã¹ãŠã®ã¡ãœããããã®ãã©ã³ã¶ã¯ã·ã§ã³ã«ã¢ã¯ã»ã¹ã§ããŸãã
sessionFactory.openSessionïŒïŒãåŒã³åºããšããã©ã³ã¶ã¯ã·ã§ã³ã«é¢é£ããªãå®å
šã«ç°ãªãã»ãã·ã§ã³ãéããŸãã
rollbackForãã©ã¡ãŒã¿ãŒã¯ããã©ã³ã¶ã¯ã·ã§ã³ãããŒã«ããã¯ããããŒã«ããã¯ã®äŸå€ãæå®ããŸãã éãã©ã¡ãŒã¿ãŒ
-noRollbackForããããŸããããã¯ãäžèšã®ãã¹ãŠã®äŸå€ã®çµæããã©ã³ã¶ã¯ã·ã§ã³ãããŒã«ããã¯ãããããšã瀺ããŸãã
äŒæãã©ã¡ãŒã¿ãæãè峿·±ãã§ãã 圌ã¯ååŒã®åºããã®ååã瀺ããŠããŸãã
org.springframework.transaction.annotation.Propagationåæããä»»æã®å€ãååŸã§ããŸãã 以äžã«äŸã瀺ããŸãã
@Autowired private SessionFactory sessionFactory; @Autowired private UserDao userDao; @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {ConstraintViolationException.class}) public Long saveTask(Long userId) { Session session = sessionFactory.getCurrentSession(); User user = userDao.getUserByLogin("user1"); Tasks task = new Tasks(); task.setName(" 1"); ... task.setUser(user); session.saveOrUpdate(task); return task.getTaskId(); }
UserDao.getUserByLoginïŒïŒã¡ãœããã¯ã
@ Transactionalã¢ãããŒã·ã§ã³ã§ã¿ã°ä»ãããããšãã§ã
ãŸã ã ãããŠãããã§
äŒæãã©ã¡ãŒã¿ãŒã¯ã
saveTaskïŒïŒã¡ãœãããã©ã³ã¶ã¯ã·ã§ã³ã«é¢é£ãã
UserDao.getUserByLoginïŒïŒã¡ãœããã®åäœã決å®ããŸãã
- Propagation.REQUIRED-æ¢åã®ãã©ã³ã¶ã¯ã·ã§ã³ãããå Žåã¯å®è¡ããååšããªãå Žåã¯æ°ãããã©ã³ã¶ã¯ã·ã§ã³ãäœæããŸãã
- Propagation.MANDATORY-æ¢åã®ãã©ã³ã¶ã¯ã·ã§ã³ã§å®è¡ããååšããå Žåã¯äŸå€ãã¹ããŒããŸãã
- Propagation.SUPPORTS-ååšããå Žåã¯æ¢åã®ãã©ã³ã¶ã¯ã·ã§ã³ã§å®è¡ããååšããªãå Žåã¯ãã©ã³ã¶ã¯ã·ã§ã³ã®å€éšã§å®è¡ããŸãã
- Propagation.NOT_SUPPORTED-åžžã«ãã©ã³ã¶ã¯ã·ã§ã³ã®å€éšã§å®è¡ãããŸãã æ¢åã®ãã®ãããå Žåã¯ã忢ããŸãã
- Propagation.REQUIRES_NEW-åžžã«æ°ããç¬ç«ãããã©ã³ã¶ã¯ã·ã§ã³ã§å®è¡ãããŸãã æ¢åã®ãã®ãããå Žåãæ°ãããã©ã³ã¶ã¯ã·ã§ã³ãå®äºãããŸã§åæ¢ããŸãã
- Propagation.NESTED-çŸåšã®ãã©ã³ã¶ã¯ã·ã§ã³ãããå Žåãæ°ããããããããã¹ãããããã©ã³ã¶ã¯ã·ã§ã³ã§å®è¡ããŸãã ãã¹ãããããã©ã³ã¶ã¯ã·ã§ã³ããã£ã³ã»ã«ãããå Žåãããã¯å€éšãã©ã³ã¶ã¯ã·ã§ã³ã«åœ±é¿ããŸããã å€éšãã©ã³ã¶ã¯ã·ã§ã³ããã£ã³ã»ã«ããããšããã¹ãããããã©ã³ã¶ã¯ã·ã§ã³ã¯ãã£ã³ã»ã«ãããŸãã çŸåšã®ãã©ã³ã¶ã¯ã·ã§ã³ããªãå Žåãæ°ãããã©ã³ã¶ã¯ã·ã§ã³ãäœæãããŸãã
- Propagation.NEVER-åžžã«ãã©ã³ã¶ã¯ã·ã§ã³ã®å€éšã§å®è¡ããæ¢åã®ãã©ã³ã¶ã¯ã·ã§ã³ãããå Žåã¯äŸå€ãã¹ããŒããŸãã
ãã©ã³ã¶ã¯ã·ã§ã³ã«é¢ããè¯ã
ãã® ã ãã©ã³ã¶ã¯ã·ã§ã³ã䜿çšãããšãããã©ãŒãã³ã¹ã«è¿œå ã®ã³ã¹ãããããããšã«æ³šæããŠãã ããã
èŠçŽãããš
ç§ã®èšäºã§ã¯ãHibernateã§ã»ãã·ã§ã³ãšãã©ã³ã¶ã¯ã·ã§ã³ãæäœããæãåºæ¬çãªååãåãäžããŸããã ãã®èšäºããJavaããã°ã©ããŒãHibernateã©ã€ãã©ãªïŒãããããã¹ãŠã®äººã§ã¯ãªãïŒã®ã¹ãŒããŒã¯ã©ã¹ã«ã€ããŠåŠç¿ããéã®æåã®ãããå€ãå
æããã®ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã è€éã§è峿·±ãããã°ã©ãã³ã°ã¢ã¯ãã£ããã£ã§ã®æåããç¥ãããŸãã
ãµã³ãã«ãããžã§ã¯ã ã
ãæž
èŽããããšãããããŸããïŒ