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(); // <i>transient-object</i> user.setLogin("user"); user.setPassword("user"); ... task.setUser(user); session.saveOrUpdate(task); //
æ³šïŒ ãŠãŒã¶ãŒãã£ãŒã«ãã®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)); // session.saveOrUpdate(task); ...
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ã©ã€ãã©ãªïŒãããããã¹ãŠã®äººã§ã¯ãªãïŒã®ã¹ãŒããŒã¯ã©ã¹ã«ã€ããŠåŠç¿ããéã®æåã®ãããå€ãå æããã®ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã è€éã§è峿·±ãããã°ã©ãã³ã°ã¢ã¯ãã£ããã£ã§ã®æåããç¥ãããŸãã
ãµã³ãã«ãããžã§ã¯ã ã
ãæž èŽããããšãããããŸããïŒ