| margaretha | 38d530e | 2017-07-11 19:06:50 +0200 | [diff] [blame] | 1 | package de.ids_mannheim.korap.dao; |
| 2 | |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 3 | import java.util.List; |
| 4 | |
| margaretha | d3c0fc9 | 2017-10-25 15:03:32 +0200 | [diff] [blame] | 5 | import org.springframework.stereotype.Repository; |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 6 | import org.springframework.transaction.annotation.Transactional; |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 7 | |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 8 | import de.ids_mannheim.korap.constant.AnnotationType; |
| margaretha | 5b70879 | 2023-05-12 16:55:29 +0200 | [diff] [blame] | 9 | import de.ids_mannheim.korap.core.entity.Annotation; |
| 10 | import de.ids_mannheim.korap.core.entity.AnnotationKey; |
| 11 | import de.ids_mannheim.korap.core.entity.AnnotationKey_; |
| 12 | import de.ids_mannheim.korap.core.entity.AnnotationLayer; |
| 13 | import de.ids_mannheim.korap.core.entity.AnnotationLayer_; |
| 14 | import de.ids_mannheim.korap.core.entity.Annotation_; |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 15 | import de.ids_mannheim.korap.exceptions.KustvaktException; |
| 16 | import de.ids_mannheim.korap.utils.ParameterChecker; |
| margaretha | 6e79684 | 2023-08-17 15:10:45 +0200 | [diff] [blame] | 17 | import jakarta.persistence.EntityManager; |
| 18 | import jakarta.persistence.NoResultException; |
| 19 | import jakarta.persistence.PersistenceContext; |
| 20 | import jakarta.persistence.Query; |
| 21 | import jakarta.persistence.criteria.CriteriaBuilder; |
| 22 | import jakarta.persistence.criteria.CriteriaQuery; |
| 23 | import jakarta.persistence.criteria.Predicate; |
| 24 | import jakarta.persistence.criteria.Root; |
| margaretha | 38d530e | 2017-07-11 19:06:50 +0200 | [diff] [blame] | 25 | |
| 26 | /** |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 27 | * AnnotationDao manages queries to database regarding annotations |
| 28 | * including |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 29 | * foundry and layer pairs. |
| margaretha | 38d530e | 2017-07-11 19:06:50 +0200 | [diff] [blame] | 30 | * |
| 31 | * @author margaretha |
| 32 | * |
| 33 | */ |
| margaretha | d3c0fc9 | 2017-10-25 15:03:32 +0200 | [diff] [blame] | 34 | @Repository |
| margaretha | 38d530e | 2017-07-11 19:06:50 +0200 | [diff] [blame] | 35 | public class AnnotationDao { |
| 36 | |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 37 | @PersistenceContext |
| 38 | private EntityManager entityManager; |
| margaretha | 38d530e | 2017-07-11 19:06:50 +0200 | [diff] [blame] | 39 | |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 40 | /** |
| margaretha | a14f1c2 | 2017-07-19 18:51:04 +0200 | [diff] [blame] | 41 | * Retrieves all foundry-layer pairs. |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 42 | * |
| margaretha | a14f1c2 | 2017-07-19 18:51:04 +0200 | [diff] [blame] | 43 | * @return a list of foundry-layer pairs. |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 44 | */ |
| margaretha | dc51507 | 2018-08-03 17:01:19 +0200 | [diff] [blame] | 45 | @SuppressWarnings("unchecked") |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 46 | public List<AnnotationLayer> getAllFoundryLayerPairs () { |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 47 | CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 48 | CriteriaQuery<AnnotationLayer> query = criteriaBuilder |
| 49 | .createQuery(AnnotationLayer.class); |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 50 | Root<AnnotationLayer> layer = query.from(AnnotationLayer.class); |
| 51 | layer.fetch(AnnotationLayer_.foundry); |
| 52 | layer.fetch(AnnotationLayer_.layer); |
| 53 | query.select(layer); |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 54 | Query q = entityManager.createQuery(query); |
| 55 | return q.getResultList(); |
| margaretha | 38d530e | 2017-07-11 19:06:50 +0200 | [diff] [blame] | 56 | } |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 57 | |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 58 | /** |
| margaretha | a14f1c2 | 2017-07-19 18:51:04 +0200 | [diff] [blame] | 59 | * Retrieves foundry-layer pairs and their values for the given |
| 60 | * foundry and layer. If layer is empty, retrieves data for all |
| 61 | * layer in the given foundry. If foundry is empty, retrieves data |
| 62 | * for all foundry and layer pairs. |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 63 | * |
| margaretha | 50179c8 | 2017-07-20 15:36:05 +0200 | [diff] [blame] | 64 | * @param foundry |
| 65 | * a foundry code |
| 66 | * @param layer |
| 67 | * a layer code |
| margaretha | a14f1c2 | 2017-07-19 18:51:04 +0200 | [diff] [blame] | 68 | * @return a list of foundry-layer pairs. |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 69 | */ |
| margaretha | dc51507 | 2018-08-03 17:01:19 +0200 | [diff] [blame] | 70 | @SuppressWarnings("unchecked") |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 71 | public List<AnnotationLayer> getAnnotationDescriptions (String foundry, |
| margaretha | a14f1c2 | 2017-07-19 18:51:04 +0200 | [diff] [blame] | 72 | String layer) { |
| margaretha | 50179c8 | 2017-07-20 15:36:05 +0200 | [diff] [blame] | 73 | |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 74 | CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 75 | CriteriaQuery<Object> query = criteriaBuilder.createQuery(); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 76 | Root<AnnotationLayer> annotationPair = query |
| 77 | .from(AnnotationLayer.class); |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 78 | annotationPair.fetch(AnnotationLayer_.foundry); |
| 79 | annotationPair.fetch(AnnotationLayer_.layer); |
| 80 | annotationPair.fetch(AnnotationLayer_.keys); |
| margaretha | 50179c8 | 2017-07-20 15:36:05 +0200 | [diff] [blame] | 81 | |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 82 | // EM: Hibernate bug in join n:m (see AnnotationPair.values). |
| 83 | // There should not be any redundant AnnotationPair. |
| 84 | // The redundancy can be also avoided with |
| 85 | // fetch=FetchType.EAGER |
| 86 | // because Hibernate does 2 selects. |
| margaretha | 50179c8 | 2017-07-20 15:36:05 +0200 | [diff] [blame] | 87 | query.distinct(true); |
| margaretha | a14f1c2 | 2017-07-19 18:51:04 +0200 | [diff] [blame] | 88 | query = query.select(annotationPair); |
| margaretha | 50179c8 | 2017-07-20 15:36:05 +0200 | [diff] [blame] | 89 | |
| margaretha | a14f1c2 | 2017-07-19 18:51:04 +0200 | [diff] [blame] | 90 | if (!foundry.isEmpty()) { |
| margaretha | d3c0fc9 | 2017-10-25 15:03:32 +0200 | [diff] [blame] | 91 | Predicate foundryPredicate = criteriaBuilder.equal(annotationPair |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 92 | .get(AnnotationLayer_.foundry).get(Annotation_.code), |
| margaretha | d3c0fc9 | 2017-10-25 15:03:32 +0200 | [diff] [blame] | 93 | foundry); |
| margaretha | a14f1c2 | 2017-07-19 18:51:04 +0200 | [diff] [blame] | 94 | if (layer.isEmpty() || layer.equals("*")) { |
| 95 | query.where(foundryPredicate); |
| 96 | } |
| 97 | else { |
| margaretha | d3c0fc9 | 2017-10-25 15:03:32 +0200 | [diff] [blame] | 98 | Predicate layerPredicate = criteriaBuilder.equal(annotationPair |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 99 | .get(AnnotationLayer_.layer).get(Annotation_.code), |
| margaretha | d3c0fc9 | 2017-10-25 15:03:32 +0200 | [diff] [blame] | 100 | layer); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 101 | Predicate andPredicate = criteriaBuilder.and(foundryPredicate, |
| 102 | layerPredicate); |
| margaretha | a14f1c2 | 2017-07-19 18:51:04 +0200 | [diff] [blame] | 103 | query.where(andPredicate); |
| 104 | } |
| 105 | } |
| 106 | |
| margaretha | e353dfa | 2017-07-18 19:23:29 +0200 | [diff] [blame] | 107 | Query q = entityManager.createQuery(query); |
| 108 | return q.getResultList(); |
| 109 | } |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 110 | |
| 111 | public Annotation retrieveAnnotation (String code, String type) { |
| 112 | CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 113 | CriteriaQuery<Annotation> query = criteriaBuilder |
| 114 | .createQuery(Annotation.class); |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 115 | |
| 116 | Root<Annotation> annotation = query.from(Annotation.class); |
| 117 | Predicate predicates = criteriaBuilder.and( |
| 118 | criteriaBuilder.equal(annotation.get(Annotation_.code), code), |
| 119 | criteriaBuilder.equal(annotation.get(Annotation_.type), type)); |
| 120 | query.select(annotation).where(predicates); |
| 121 | Query q = entityManager.createQuery(query); |
| 122 | try { |
| 123 | return (Annotation) q.getSingleResult(); |
| 124 | } |
| 125 | catch (NoResultException e) { |
| 126 | return null; |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | public AnnotationLayer retrieveAnnotationLayer (String foundry, |
| 131 | String layer) { |
| 132 | Annotation ann1 = retrieveAnnotation(foundry, AnnotationType.FOUNDRY); |
| 133 | Annotation ann2 = retrieveAnnotation(layer, AnnotationType.LAYER); |
| 134 | |
| 135 | CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 136 | CriteriaQuery<AnnotationLayer> query = criteriaBuilder |
| 137 | .createQuery(AnnotationLayer.class); |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 138 | |
| 139 | Root<AnnotationLayer> annotation = query.from(AnnotationLayer.class); |
| 140 | Predicate predicates = criteriaBuilder.and( |
| 141 | criteriaBuilder.equal(annotation.get(AnnotationLayer_.foundry), |
| 142 | ann1), |
| 143 | criteriaBuilder.equal(annotation.get(AnnotationLayer_.layer), |
| 144 | ann2)); |
| 145 | query.select(annotation).where(predicates); |
| 146 | Query q = entityManager.createQuery(query); |
| 147 | try { |
| 148 | return (AnnotationLayer) q.getSingleResult(); |
| 149 | } |
| 150 | catch (NoResultException e) { |
| 151 | return null; |
| 152 | } |
| 153 | |
| 154 | } |
| 155 | |
| margaretha | d3a46ec | 2019-12-20 12:18:44 +0100 | [diff] [blame] | 156 | @Transactional |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 157 | public Annotation createAnnotation (String code, String type, String text, |
| 158 | String description) { |
| 159 | Annotation ann = new Annotation(code, type, text, description); |
| 160 | entityManager.persist(ann); |
| 161 | return ann; |
| 162 | } |
| 163 | |
| margaretha | d3a46ec | 2019-12-20 12:18:44 +0100 | [diff] [blame] | 164 | @Transactional |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 165 | public AnnotationLayer createAnnotationLayer (Annotation foundry, |
| 166 | Annotation layer) throws KustvaktException { |
| 167 | ParameterChecker.checkObjectValue(foundry, "foundry"); |
| 168 | ParameterChecker.checkObjectValue(layer, "layer"); |
| 169 | |
| 170 | AnnotationLayer annotationLayer = new AnnotationLayer(); |
| 171 | annotationLayer.setFoundryId(foundry.getId()); |
| 172 | annotationLayer.setLayerId(layer.getId()); |
| 173 | annotationLayer.setDescription( |
| 174 | foundry.getDescription() + " " + layer.getDescription()); |
| 175 | entityManager.persist(annotationLayer); |
| 176 | return annotationLayer; |
| 177 | } |
| 178 | |
| margaretha | d3a46ec | 2019-12-20 12:18:44 +0100 | [diff] [blame] | 179 | @Transactional |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 180 | public void updateAnnotationLayer (AnnotationLayer layer) { |
| 181 | entityManager.merge(layer); |
| 182 | } |
| 183 | |
| margaretha | d3a46ec | 2019-12-20 12:18:44 +0100 | [diff] [blame] | 184 | @Transactional |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 185 | public void updateAnnotationKey (AnnotationKey key) { |
| 186 | entityManager.merge(key); |
| 187 | } |
| 188 | |
| margaretha | d3a46ec | 2019-12-20 12:18:44 +0100 | [diff] [blame] | 189 | @Transactional |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 190 | public AnnotationKey createAnnotationKey (AnnotationLayer layer, |
| 191 | Annotation key) { |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 192 | AnnotationKey annotation = new AnnotationKey(layer.getId(), |
| 193 | key.getId()); |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 194 | entityManager.persist(annotation); |
| 195 | return annotation; |
| 196 | } |
| 197 | |
| 198 | public AnnotationKey retrieveAnnotationKey (AnnotationLayer layer, |
| 199 | Annotation key) { |
| 200 | |
| 201 | CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 202 | CriteriaQuery<AnnotationKey> query = criteriaBuilder |
| 203 | .createQuery(AnnotationKey.class); |
| margaretha | 51e5e3f | 2018-10-17 15:10:03 +0200 | [diff] [blame] | 204 | |
| 205 | Root<AnnotationKey> annotation = query.from(AnnotationKey.class); |
| 206 | Predicate predicates = criteriaBuilder.and( |
| 207 | criteriaBuilder.equal(annotation.get(AnnotationKey_.layer), |
| 208 | layer), |
| 209 | criteriaBuilder.equal(annotation.get(AnnotationKey_.key), key)); |
| 210 | query.select(annotation).where(predicates); |
| 211 | Query q = entityManager.createQuery(query); |
| 212 | try { |
| 213 | return (AnnotationKey) q.getSingleResult(); |
| 214 | } |
| 215 | catch (NoResultException e) { |
| 216 | return null; |
| 217 | } |
| 218 | } |
| margaretha | 38d530e | 2017-07-11 19:06:50 +0200 | [diff] [blame] | 219 | } |