Changeset 2614
- Timestamp:
- 02/02/10 17:23:13 (2 years ago)
- Location:
- maven_sequence_lims/molgenis3_4_maven
- Files:
-
- 8 edited
-
pom.xml (modified) (2 diffs)
-
src/main/java/org/molgenis/framework/data/jdbc/JDBCConnectionHelper.java (modified) (1 diff)
-
src/main/java/org/molgenis/framework/data/jpa/JPAQueryGeneratorUtil.java (modified) (2 diffs)
-
src/main/java/org/molgenis/framework/data/jpa/JpaDatabase.java (modified) (2 diffs)
-
src/main/java/org/molgenis/framework/data/jpa/JpaMapper.java (modified) (2 diffs)
-
src/main/java/org/molgenis/framework/data/paging/AbstractPager.java (modified) (1 diff)
-
src/main/java/org/molgenis/generators/data/types/DataTypeGen.java.ftl (modified) (2 diffs)
-
src/main/java/org/molgenis/generators/data/types/JpaDataTypeGen.java.ftl (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
maven_sequence_lims/molgenis3_4_maven/pom.xml
r2586 r2614 9 9 <url>http://maven.apache.org</url> 10 10 <dependencies> 11 <dependency> 12 <groupId>javax</groupId> 13 <artifactId>javaee-web-api</artifactId> 14 <version>6.0</version> 15 <scope>provided</scope> 16 </dependency> 11 17 <dependency> 12 18 <groupId>junit</groupId> … … 55 61 <version>1.6.5</version> 56 62 </dependency> 57 <dependency>63 <!-- <dependency> 58 64 <groupId>javax.persistence</groupId> 59 65 <artifactId>persistence-api</artifactId> 60 66 <version>1.0</version> 61 </dependency> 67 </dependency>--> 62 68 <dependency> 63 69 <groupId>log4j</groupId> -
maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/framework/data/jdbc/JDBCConnectionHelper.java
r2582 r2614 398 398 // where_clause.append(tablePrefix + rule.getField() + " " + 399 399 // operator + " '" + value + "'"); 400 if (rule.getOperator().equals(Operator.JOIN)) where_clause.append(rule.getField() + " " + operator401 + " " + value + "");400 if (rule.getOperator().equals(Operator.JOIN)) 401 where_clause.append(rule.getField() + " " + operator + " " + value + ""); 402 402 else 403 403 { -
maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/framework/data/jpa/JPAQueryGeneratorUtil.java
r2582 r2614 2 2 3 3 import java.util.List; 4 import javax.persistence.EntityManager; 5 import javax.persistence.criteria.CriteriaBuilder; 6 import javax.persistence.criteria.CriteriaQuery; 7 import javax.persistence.criteria.Expression; 8 import javax.persistence.criteria.Predicate; 9 import javax.persistence.criteria.Root; 10 import javax.persistence.metamodel.EntityType; 11 import javax.persistence.metamodel.Metamodel; 4 12 5 13 import org.apache.commons.lang.StringEscapeUtils; … … 8 16 import org.molgenis.framework.data.QueryRule.Operator; 9 17 import org.molgenis.framework.data.jdbc.ColumnInfo.Type; 18 import org.molgenis.util.Entity; 10 19 11 20 /** 12 * Fixme: dit moet vervangen worden de creteria look-a-like api die in JPA 2.013 * komt!14 * Fixme: testen! aangezien dit gemaakt was voor SQL en niet voor JPA-Query-Language15 * @author Morris Swertz16 21 * @author jorislops 17 22 */ 18 23 19 public class JPAQueryGeneratorUtil 20 { 21 public static String createWhereSql(JpaMapper mapper, boolean isNested, boolean withOffset, 22 Integer[] limitOffset, QueryRule... rules) throws DatabaseException 23 { 24 StringBuffer where_clause = new StringBuffer(""); 25 for (QueryRule r : rules) 26 { 27 QueryRule rule = new QueryRule(r); //copy because of side effects 28 //logger.debug(rule); 29 30 //String tablePrefix = ""; 31 if(mapper != null) 32 rule.setField(mapper.getTableFieldName(rule.getField())); 33 34 if (rule.getOperator() == Operator.LAST || rule.getOperator() == Operator.LIMIT 35 || rule.getOperator() == Operator.OFFSET || rule.getOperator() == Operator.SORTASC 36 || rule.getOperator() == Operator.SORTDESC) 37 { 38 39 } 40 else if (rule.getOperator() == QueryRule.Operator.NESTED) 41 { 42 QueryRule[] nestedrules = rule.getNestedRules(); 43 if (nestedrules.length > 0) 44 { 45 if (where_clause.length() > 0) 46 { 47 if (rule.isOr()) 48 where_clause.append(" OR "); 49 else 50 where_clause.append(" AND "); 51 } 52 where_clause.append("("); 53 where_clause.append(createWhereSql(mapper, true, false, null, nestedrules)); 54 where_clause.append(")"); 55 } 56 } 57 else if (rule.getOperator() == QueryRule.Operator.IN) 58 { 59 if (where_clause.length() > 0) 60 { 61 if (rule.isOr()) 62 where_clause.append(" OR "); 63 else 64 where_clause.append(" AND "); 65 } 66 67 //where_clause.append(tablePrefix + rule.getField() + " IN("); 68 where_clause.append(rule.getField() + " IN("); 69 70 Object[] values = new Object[0]; 71 if (rule.getValue() instanceof List) 72 { 73 values = ((List<Object>) rule.getValue()).toArray(); 74 } 75 else 76 { 77 values = (Object[]) rule.getValue(); 78 } 79 80 for (int i = 0; i < values.length; i++) 81 { 82 if (i > 0) where_clause.append(","); 83 if (mapper != null && omitQuotes(mapper.getFieldType(rule.getField()))) 84 { 85 //where_clause.append(values[i] 86 // .toString()); 87 where_clause.append("'" + escapeSql(values[i]) + "'"); 88 } 89 else 90 { 91 where_clause.append("'" + escapeSql(values[i]) + "'"); 92 } 93 } 94 where_clause.append(") "); 95 } 96 else 97 // where clause 98 { 99 // check validity of the rule 100 //if(rule.getField() == null || columnInfoMap.get(rule.getField()) == null ) 101 //{ 102 // throw new DatabaseException("Invalid rule: field '"+ rule.getField() + "' not known."); 103 //} 104 105 String operator = ""; 106 switch (rule.getOperator()) 107 { 108 case EQUALS: 109 operator = "="; 110 break; 111 case NOT: 112 operator = "!="; 113 break; 114 case LIKE: 115 operator = "LIKE"; 116 break; 117 case LESS: 118 operator = "<"; 119 break; 120 case GREATER: 121 operator = ">"; 122 break; 123 case LESS_EQUAL: 124 operator = "<="; 125 break; 126 case GREATER_EQUAL: 127 operator = ">="; 128 break; 129 } 130 // if (rule.getField() != "" && operator != "" && 131 // rule.getValue() != "") 132 // { 133 if (where_clause.length() > 0) 134 { 135 if (rule.isOr()) where_clause.append(" OR "); 136 else 137 where_clause.append(" AND "); 138 } 139 if(new Boolean(true).equals(rule.getValue())) rule.setValue("1"); 140 if(new Boolean(false).equals(rule.getValue())) rule.setValue("0"); 141 Object value = rule.getValue() == null ? "NULL" : escapeSql(rule.getValue()); 142 if (!value.equals("NULL") && rule.getOperator() == Operator.LIKE && mapper != null && !omitQuotes(mapper.getFieldType(rule.getField()))) 143 { 144 if( !value.toString().trim().startsWith("%") && !value.toString().trim().endsWith("%") ) 145 { 146 value = "%"+value+"%"; 147 } 148 } 149 150 //if (omitQuotes(columnInfoMap.get(rule.getField()).getType())) 151 // where_clause.append(tablePrefix + rule.getField() + " " + operator + " " + value + ""); 152 //else 153 //where_clause.append(tablePrefix + rule.getField() + " " + operator + " '" + value + "'"); 154 where_clause.append(rule.getField() + " " + operator + " '" + value + "'"); 155 // } 156 } 157 } 158 159 String result = where_clause.toString(); 160 if (!isNested && where_clause.length() > 0) result = " WHERE " + result; 161 createLimitSql(withOffset, rules, limitOffset); 162 return result + createSortSql(mapper, rules); 163 } 164 165 /** Helper method for creating a sort clause */ 166 private static String createSortSql(JpaMapper mapper, QueryRule... rules) 167 { 168 return createSortSql(mapper, false, rules); 169 } 170 171 private static boolean omitQuotes(Type t) 172 { 173 return t == Type.LONG || t == Type.INT || t == Type.DECIMAL; 174 175 } 176 177 /** 178 * Helper method for creating a sort clause 179 * 180 * @param tableName 181 * name of the table that is used to prefix column names. 182 * @param reverseSorting 183 * to reverese sorting order. This is used when trying to find 184 * the "last records" in a sorted list by instead finding the 185 * "first records" in the reversly ordered list. 186 * @param rules 187 * query rules to be translated into sql order by clause. 188 * @return sql with sort clause 189 */ 190 public static String createSortSql(JpaMapper mapper, boolean reverseSorting, QueryRule rules[]) 191 { 192 193 for (QueryRule rule : rules) 194 { 195 if (rule.getOperator() == Operator.LAST) 196 { 197 reverseSorting = !reverseSorting; 198 break; 199 } 200 } 201 202 String sort_clause = ""; 203 for (QueryRule r : rules) 204 { 205 QueryRule rule = new QueryRule(r); //copy because of sideeffects 206 207 // limit clause 208 if ((rule.getOperator() == Operator.SORTASC && !reverseSorting) 209 || (reverseSorting && rule.getOperator() == Operator.SORTDESC)) 210 { 211 if(mapper != null) rule.setValue(mapper.getTableFieldName(rule.getValue().toString())); 212 sort_clause += rule.getValue().toString() + " ASC,"; 213 } 214 else if ((rule.getOperator() == QueryRule.Operator.SORTDESC && !reverseSorting) 215 || (reverseSorting && rule.getOperator() == Operator.SORTASC)) 216 { 217 if(mapper != null) rule.setValue(mapper.getTableFieldName(rule.getValue().toString())); 218 sort_clause += rule.getValue().toString() + " DESC,"; 219 } 220 } 221 if(sort_clause.length() > 0) 222 return " ORDER BY "+sort_clause.substring(0,sort_clause.lastIndexOf(",")); 223 return sort_clause; 224 } 225 226 /** 227 * Helper method for creating a limit clause 228 * 229 * @param withOffset 230 * Indicate whether offset is to be used. If false the limit 231 * clause is kept empty. 232 * @param rules 233 * query rules to be translated into SQL order by clause. 234 * @param limit 235 * out: limit count of the query (returns null if no limit is found in the rules) 236 * @param offset 237 * out: offset of the query (returns null if no offset is found in the rules); 238 * @return limit,offset as output parameters 239 */ 240 public static void createLimitSql(boolean withOffset, QueryRule[] rules, Integer[] limitOffset) { 241 boolean limitFound = false; 242 boolean offsetFound = false; 243 for (QueryRule rule : rules) { 244 if (rule.getOperator() == QueryRule.Operator.LIMIT) { 245 limitOffset[0] = new Integer((Integer)rule.getValue()); 246 limitFound = true; 247 } else if (rule.getOperator() == QueryRule.Operator.OFFSET) { 248 limitOffset[1] = new Integer((Integer)rule.getValue()); 249 offsetFound = true; 250 } 251 } 252 } 253 254 /** 255 * Helper method for creating an escaped sql string for a value. 256 * <p> 257 * This can be used by createXXXsql methods to prevend sql-injection in data 258 * values. 259 * 260 * @param value 261 * to be escaped 262 */ 263 public static String escapeSql(Object value) 264 { 265 return StringEscapeUtils.escapeSql(value.toString()); 266 // return sql.toString().replace("'", "''"); 267 } 24 public class JPAQueryGeneratorUtil { 25 26 public static <E extends Entity> Predicate createWhere( 27 Class<E> klass, JpaMapper mapper, EntityManager em, Root<E> root, 28 CriteriaQuery cq, CriteriaBuilder cb, QueryRule... rules) { 29 Predicate whereClause = null; 30 31 for (QueryRule r : rules) { 32 QueryRule rule = new QueryRule(r); 33 if (mapper != null) { 34 rule.setField(mapper.getTableFieldName(rule.getField())); 35 36 boolean whereConditon = !(rule.getOperator() == Operator.LAST || rule.getOperator() == Operator.LIMIT 37 || rule.getOperator() == Operator.OFFSET || rule.getOperator() == Operator.SORTASC 38 || rule.getOperator() == Operator.SORTDESC || rule.getOperator() == QueryRule.Operator.NESTED 39 || rule.getOperator() == QueryRule.Operator.IN); 40 if (whereConditon) { 41 Predicate predicate = null; 42 43 String field = rule.getField(); 44 45 if(rule.getValue() == null) { 46 predicate = root.get(field).isNull(); 47 } else { 48 switch (rule.getOperator()) { 49 case EQUALS: 50 predicate = cb.equal(root.get(field), rule.getValue()); 51 break; 52 case NOT: 53 predicate = cb.notEqual(root.get(field), rule.getValue()); 54 break; 55 case LIKE: 56 predicate = cb.like(root.get(field).as(String.class), (String)rule.getValue()); 57 break; 58 case LESS: 59 predicate = cb.lessThan(root.get(field).as(String.class), (Comparable)rule.getValue() ); 60 break; 61 case GREATER: 62 predicate = cb.greaterThan(root.get(field).as(String.class), (Comparable)rule.getValue() ); 63 break; 64 case LESS_EQUAL: 65 predicate = cb.lessThanOrEqualTo(root.get(field).as(String.class), (Comparable)rule.getValue() ); 66 break; 67 case GREATER_EQUAL: 68 predicate = cb.greaterThanOrEqualTo(root.get(field).as(String.class), (Comparable)rule.getValue() ); 69 break; 70 } 71 } 72 73 //compound coundition (and & or) 74 if(whereClause != null) { 75 assert predicate != null : rule.getOperator(); 76 77 if(rule.isOr()) { 78 whereClause = cb.or(whereClause, predicate); 79 } else { 80 whereClause = cb.and(whereClause, predicate); 81 } 82 } else { 83 whereClause = predicate; 84 } 85 } 86 } 87 } 88 return whereClause; 89 } 90 91 public static void createSort() { 92 } 93 94 public static String createWhereSql(JpaMapper mapper, boolean isNested, boolean withOffset, 95 Integer[] limitOffset, QueryRule... rules) throws DatabaseException { 96 StringBuffer where_clause = new StringBuffer(""); 97 for (QueryRule r : rules) { 98 QueryRule rule = new QueryRule(r); //copy because of side effects 99 //logger.debug(rule); 100 101 //String tablePrefix = ""; 102 if (mapper != null) { 103 rule.setField(mapper.getTableFieldName(rule.getField())); 104 } 105 106 if (rule.getOperator() == Operator.LAST || rule.getOperator() == Operator.LIMIT 107 || rule.getOperator() == Operator.OFFSET || rule.getOperator() == Operator.SORTASC 108 || rule.getOperator() == Operator.SORTDESC) { 109 } else if (rule.getOperator() == QueryRule.Operator.NESTED) { 110 QueryRule[] nestedrules = rule.getNestedRules(); 111 if (nestedrules.length > 0) { 112 if (where_clause.length() > 0) { 113 if (rule.isOr()) { 114 where_clause.append(" OR "); 115 } else { 116 where_clause.append(" AND "); 117 } 118 } 119 where_clause.append("("); 120 where_clause.append(createWhereSql(mapper, true, false, null, nestedrules)); 121 where_clause.append(")"); 122 } 123 } else if (rule.getOperator() == QueryRule.Operator.IN) { 124 if (where_clause.length() > 0) { 125 if (rule.isOr()) { 126 where_clause.append(" OR "); 127 } else { 128 where_clause.append(" AND "); 129 } 130 } 131 132 //where_clause.append(tablePrefix + rule.getField() + " IN("); 133 where_clause.append(rule.getField() + " IN("); 134 135 Object[] values = new Object[0]; 136 if (rule.getValue() instanceof List) { 137 values = ((List<Object>) rule.getValue()).toArray(); 138 } else { 139 values = (Object[]) rule.getValue(); 140 } 141 142 for (int i = 0; i < values.length; i++) { 143 if (i > 0) { 144 where_clause.append(","); 145 } 146 if (mapper != null && omitQuotes(mapper.getFieldType(rule.getField()))) { 147 //where_clause.append(values[i] 148 // .toString()); 149 where_clause.append("'" + escapeSql(values[i]) + "'"); 150 } else { 151 where_clause.append("'" + escapeSql(values[i]) + "'"); 152 } 153 } 154 where_clause.append(") "); 155 } else // where clause 156 { 157 // check validity of the rule 158 //if(rule.getField() == null || columnInfoMap.get(rule.getField()) == null ) 159 //{ 160 // throw new DatabaseException("Invalid rule: field '"+ rule.getField() + "' not known."); 161 //} 162 163 String operator = ""; 164 switch (rule.getOperator()) { 165 case EQUALS: 166 operator = "="; 167 break; 168 case NOT: 169 operator = "!="; 170 break; 171 case LIKE: 172 operator = "LIKE"; 173 break; 174 case LESS: 175 operator = "<"; 176 break; 177 case GREATER: 178 operator = ">"; 179 break; 180 case LESS_EQUAL: 181 operator = "<="; 182 break; 183 case GREATER_EQUAL: 184 operator = ">="; 185 break; 186 } 187 // if (rule.getField() != "" && operator != "" && 188 // rule.getValue() != "") 189 // { 190 if (where_clause.length() > 0) { 191 if (rule.isOr()) { 192 where_clause.append(" OR "); 193 } else { 194 where_clause.append(" AND "); 195 } 196 } 197 if (new Boolean(true).equals(rule.getValue())) { 198 rule.setValue("1"); 199 } 200 if (new Boolean(false).equals(rule.getValue())) { 201 rule.setValue("0"); 202 } 203 Object value = rule.getValue() == null ? "NULL" : escapeSql(rule.getValue()); 204 if (!value.equals("NULL") && rule.getOperator() == Operator.LIKE && mapper != null && !omitQuotes(mapper.getFieldType(rule.getField()))) { 205 if (!value.toString().trim().startsWith("%") && !value.toString().trim().endsWith("%")) { 206 value = "%" + value + "%"; 207 } 208 } 209 210 //if (omitQuotes(columnInfoMap.get(rule.getField()).getType())) 211 // where_clause.append(tablePrefix + rule.getField() + " " + operator + " " + value + ""); 212 //else 213 //where_clause.append(tablePrefix + rule.getField() + " " + operator + " '" + value + "'"); 214 where_clause.append(rule.getField() + " " + operator + " '" + value + "'"); 215 // } 216 } 217 } 218 219 String result = where_clause.toString(); 220 if (!isNested && where_clause.length() > 0) { 221 result = " WHERE " + result; 222 } 223 createLimitSql(withOffset, rules, limitOffset); 224 return result + createSortSql(mapper, rules); 225 } 226 227 /** Helper method for creating a sort clause */ 228 private static String createSortSql(JpaMapper mapper, QueryRule... rules) { 229 return createSortSql(mapper, false, rules); 230 } 231 232 private static boolean omitQuotes(Type t) { 233 return t == Type.LONG || t == Type.INT || t == Type.DECIMAL; 234 235 } 236 237 /** 238 * Helper method for creating a sort clause 239 * 240 * @param tableName 241 * name of the table that is used to prefix column names. 242 * @param reverseSorting 243 * to reverese sorting order. This is used when trying to find 244 * the "last records" in a sorted list by instead finding the 245 * "first records" in the reversly ordered list. 246 * @param rules 247 * query rules to be translated into sql order by clause. 248 * @return sql with sort clause 249 */ 250 public static String createSortSql(JpaMapper mapper, boolean reverseSorting, QueryRule rules[]) { 251 252 for (QueryRule rule : rules) { 253 if (rule.getOperator() == Operator.LAST) { 254 reverseSorting = !reverseSorting; 255 break; 256 } 257 } 258 259 String sort_clause = ""; 260 for (QueryRule r : rules) { 261 QueryRule rule = new QueryRule(r); //copy because of sideeffects 262 263 // limit clause 264 if ((rule.getOperator() == Operator.SORTASC && !reverseSorting) 265 || (reverseSorting && rule.getOperator() == Operator.SORTDESC)) { 266 if (mapper != null) { 267 rule.setValue(mapper.getTableFieldName(rule.getValue().toString())); 268 } 269 sort_clause += rule.getValue().toString() + " ASC,"; 270 } else if ((rule.getOperator() == QueryRule.Operator.SORTDESC && !reverseSorting) 271 || (reverseSorting && rule.getOperator() == Operator.SORTASC)) { 272 if (mapper != null) { 273 rule.setValue(mapper.getTableFieldName(rule.getValue().toString())); 274 } 275 sort_clause += rule.getValue().toString() + " DESC,"; 276 } 277 } 278 if (sort_clause.length() > 0) { 279 return " ORDER BY " + sort_clause.substring(0, sort_clause.lastIndexOf(",")); 280 } 281 return sort_clause; 282 } 283 284 /** 285 * Helper method for creating a limit clause 286 * 287 * @param withOffset 288 * Indicate whether offset is to be used. If false the limit 289 * clause is kept empty. 290 * @param rules 291 * query rules to be translated into SQL order by clause. 292 * @param limit 293 * out: limit count of the query (returns null if no limit is found in the rules) 294 * @param offset 295 * out: offset of the query (returns null if no offset is found in the rules); 296 * @return limit,offset as output parameters 297 */ 298 public static void createLimitSql(boolean withOffset, QueryRule[] rules, Integer[] limitOffset) { 299 boolean limitFound = false; 300 boolean offsetFound = false; 301 for (QueryRule rule : rules) { 302 if (rule.getOperator() == QueryRule.Operator.LIMIT) { 303 limitOffset[0] = new Integer((Integer) rule.getValue()); 304 limitFound = true; 305 } else if (rule.getOperator() == QueryRule.Operator.OFFSET) { 306 limitOffset[1] = new Integer((Integer) rule.getValue()); 307 offsetFound = true; 308 } 309 } 310 } 311 312 /** 313 * Helper method for creating an escaped sql string for a value. 314 * <p> 315 * This can be used by createXXXsql methods to prevend sql-injection in data 316 * values. 317 * 318 * @param value 319 * to be escaped 320 */ 321 public static String escapeSql(Object value) { 322 return StringEscapeUtils.escapeSql(value.toString()); 323 // return sql.toString().replace("'", "''"); 324 } 268 325 } -
maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/framework/data/jpa/JpaDatabase.java
r2582 r2614 13 13 import javax.persistence.EntityManager; 14 14 import javax.persistence.RollbackException; 15 import javax.persistence.criteria.CriteriaBuilder; 16 import javax.persistence.criteria.CriteriaQuery; 17 import javax.persistence.criteria.Predicate; 18 import javax.persistence.criteria.Root; 19 import javax.persistence.metamodel.EntityType; 20 import javax.persistence.metamodel.Metamodel; 15 21 16 22 import org.apache.log4j.Logger; … … 54 60 */ 55 61 public abstract class JpaDatabase implements Database { 56 enum Action { 57 ADD, UPDATE, REMOVE 58 // remov(e) because of pretty printing. 59 }; 60 61 Security login; 62 63 /** batch size */ 64 static final int BATCH_SIZE = 5000; 65 /** List of mappers, mapping entities to a JDBC connection */ 66 static Map<String, JpaMapper> mappers = new TreeMap<String, JpaMapper>(); 67 /** The filesource associated to this database: takes care of "file" fields */ 68 File fileSource; 69 /** Logger for this database */ 70 static Logger logger = Logger.getLogger(JpaDatabase.class.getSimpleName()); 71 /** Current JPA entity manager */ 72 EntityManager em; 73 /**in transaction*/ 74 boolean inTransaction; 75 76 public JpaDatabase(EntityManager em) { 77 this.em = em; 78 } 79 80 81 82 public List<Object[]> query(String qlQuery, QueryRule... rules ) throws DatabaseException { 83 84 Integer[] limitOffset = new Integer[2]; 85 qlQuery += JPAQueryGeneratorUtil.createWhereSql(null, false, true, limitOffset, rules); 86 Integer limit = limitOffset[0]; 87 Integer offset = limitOffset[1]; 88 89 javax.persistence.Query query = em.createQuery(qlQuery); 90 91 if(limit != null) { 92 query.setMaxResults(limit); 93 } 94 if(offset != null) { 95 query.setFirstResult(offset); 96 } 97 return (List<Object[]>)query.getResultList(); 98 } 99 100 @Override 101 public <E extends Entity> int count(Class<E> klazz, QueryRule... rules) 102 throws DatabaseException { 103 JpaMapper<E> mapper = getMapperFor(klazz); 104 String where = JPAQueryGeneratorUtil.createWhereSql(mapper, false, 105 true, null, rules); 106 return getMapperFor(klazz).count(where, em); 107 } 108 109 @Override 110 public <E extends Entity> List<E> findByExample(E example) 111 throws DatabaseException { 112 try { 113 Query<E> q = (Query<E>) this.query(example.getClass()); 114 for (String field : example.getFields()) { 115 if (example.get(field) != null) { 116 if (example.get(field) instanceof List) { 117 if (((List) example.get(field)).size() > 0) 118 q.in(field, (List) example.get(field)); 119 } else 120 q.equals(field, example.get(field)); 121 } 122 } 123 124 return q.find(); 125 } catch (ParseException pe) { 126 // should never happen... 127 pe.printStackTrace(); 128 } 129 return null; 130 } 131 62 63 enum Action { 64 65 ADD, UPDATE, REMOVE 66 // remov(e) because of pretty printing. 67 }; 68 Security login; 69 /** batch size */ 70 static final int BATCH_SIZE = 5000; 71 /** List of mappers, mapping entities to a JDBC connection */ 72 static Map<String, JpaMapper> mappers = new TreeMap<String, JpaMapper>(); 73 /** The filesource associated to this database: takes care of "file" fields */ 74 File fileSource; 75 /** Logger for this database */ 76 static Logger logger = Logger.getLogger(JpaDatabase.class.getSimpleName()); 77 /** Current JPA entity manager */ 78 EntityManager em; 79 /**in transaction*/ 80 boolean inTransaction; 81 82 public JpaDatabase(EntityManager em) { 83 this.em = em; 84 } 85 86 public List<Object[]> query(String qlQuery, QueryRule... rules) throws DatabaseException { 87 Integer[] limitOffset = new Integer[2]; 88 qlQuery += JPAQueryGeneratorUtil.createWhereSql(null, false, true, limitOffset, rules); 89 Integer limit = limitOffset[0]; 90 Integer offset = limitOffset[1]; 91 92 javax.persistence.Query query = em.createQuery(qlQuery); 93 94 if (limit != null) { 95 query.setMaxResults(limit); 96 } 97 if (offset != null) { 98 query.setFirstResult(offset); 99 } 100 return (List<Object[]>) query.getResultList(); 101 } 102 103 @Override 104 public <E extends Entity> int count(Class<E> klazz, QueryRule... rules) 105 throws DatabaseException { 106 CriteriaBuilder cb = em.getCriteriaBuilder(); 107 CriteriaQuery<Long> cq = cb.createQuery(Long.class); 108 Metamodel m = em.getMetamodel(); 109 Root<E> root = cq.from(klazz); 110 111 cq.select(cb.count(root.get("id"))); 112 113 JpaMapper<E> mapper = mappers.get(klazz.getName()); 114 Predicate whereClause = JPAQueryGeneratorUtil.createWhere(klazz, mapper, em, root, cq, cb, rules); 115 if(whereClause != null) 116 cq.where(whereClause); 117 118 if(!inTransaction) { 119 em.getTransaction().begin(); 120 } 121 //dit moet anders 122 int count = em.createQuery(cq).getSingleResult().intValue(); 123 if(!inTransaction) { 124 em.getTransaction().commit(); 125 } 126 return count; 127 } 128 129 @Override 130 public <E extends Entity> List<E> findByExample(E example) 131 throws DatabaseException { 132 try { 133 Query<E> q = (Query<E>) this.query(example.getClass()); 134 for (String field : example.getFields()) { 135 if (example.get(field) != null) { 136 if (example.get(field) instanceof List) { 137 if (((List) example.get(field)).size() > 0) { 138 q.in(field, (List) example.get(field)); 139 } 140 } else { 141 q.equals(field, example.get(field)); 142 } 143 } 144 } 145 146 return q.find(); 147 } catch (ParseException pe) { 148 // should never happen... 149 pe.printStackTrace(); 150 } 151 return null; 152 } 153 132 154 // @Override 133 public <E extends Entity> E findById(Class<E> klazz, Object id) { 134 return (E)em.find(klazz, id); 135 } 136 137 @Override 138 public <E extends Entity> List<E> find(Class<E> klazz, QueryRule... rules) 139 throws DatabaseException { 140 141 List<E> entities = null; 142 JpaMapper<E> mapper = this.getMapperFor(klazz); 143 144 Integer[] limitOffset = new Integer[2]; 145 String qlWhereClause = JPAQueryGeneratorUtil.createWhereSql(mapper, 146 false, true, limitOffset, rules); 147 Integer limit = limitOffset[0]; 148 Integer offset = limitOffset[1]; 149 150 //if(!inTransaction) em.getTransaction().begin(); 151 entities = (List<E>) mapper.find(qlWhereClause, limit, offset, em); 152 //if(!inTransaction) em.getTransaction().commit(); 153 154 logger.info(entities.size() + " " + klazz.getSimpleName() 155 + " objects found"); 156 157 return entities; 158 } 159 160 @Override 161 public <E extends Entity> void find(Class<E> klazz, CsvWriter writer, 162 QueryRule... rules) throws DatabaseException { 163 try { 164 JpaMapper<E> mapper = this.getMapperFor(klazz); 165 List<E> rs = executeSelect(klazz, rules); 166 // transform result set in writer 167 E entity = mapper.create(); 168 writer.writeHeader(entity); 169 int i = 0; 170 List<E> entityBatch = new ArrayList<E>(); 171 Iterator<E> iter = rs.iterator(); 172 while (iter.hasNext()) { 173 entity = iter.next(); 174 175 // JDBCTuple row = new JDBCTuple(rs); 176 // entity = mapper.create(); 177 // entity.set(row); 178 entityBatch.add(entity); 179 i++; 180 181 // write batch 182 if (i % BATCH_SIZE == 0) { 183 // load mrefs 184 // mapper.mapMrefs(this, entityBatch); 185 for (E e : entityBatch) { 186 writer.writeRow(entity); 187 } 188 entityBatch.clear(); 189 } 190 } 191 // write remaining 192 // load mrefs 193 // mapper.mapMrefs(this, entityBatch); 194 for (E e : entityBatch) { 195 writer.writeRow(e); 196 } 197 entityBatch.clear(); 198 199 logger.debug("find(" + klazz + ", CsvWriter, " 200 + Arrays.asList(rules) + "): wrote " + i + " lines."); 201 } catch (Exception e) { 202 throw new DatabaseException(e); 203 } 204 } 205 206 @Override 207 public <E extends Entity> Query<E> query(Class<E> klazz) { 208 return new QueryImp<E>(this, klazz); 209 } 210 211 @Override 212 public <E extends Entity> int add(E entity) throws DatabaseException, 213 IOException { 214 List<E> entityList = new ArrayList<E>(); 215 entityList.add(entity); 216 return this.add(entityList); 217 } 218 219 @Override 220 public <E extends Entity> int add(List<E> entities) 221 throws DatabaseException, IOException { 222 int count = 0; 223 if (entities.size() > 0) { 224 if(!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 225 em.getTransaction().begin(); 226 } 227 count = getMapperFor(entities).add(entities,em); 228 if(!inTransaction) { 229 em.getTransaction().commit(); 230 } 231 } 232 return count; 233 } 234 235 @Override 236 public <E extends Entity> int add(Class<E> klazz, CsvReader reader, 237 CsvWriter writer) throws Exception { 238 return executeUpdate(Action.ADD, klazz, reader, writer); 239 } 240 241 @Override 242 public <E extends Entity> int update(E entity) throws DatabaseException, 243 IOException { 244 List<E> entityList = new ArrayList<E>(); 245 entityList.add(entity); 246 return this.update(entityList); 247 } 248 249 @Override 250 public <E extends Entity> int update(List<E> entities) 251 throws DatabaseException, IOException { 252 int count = 0; 253 if (entities.size() > 0) 254 { 255 if(!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 256 em.getTransaction().begin(); 257 } 258 count = getMapperFor(entities).update(entities,em); 259 if(!inTransaction) { 260 em.getTransaction().commit(); 261 } 262 } 263 return count; 264 } 265 266 @Override 267 public <E extends Entity> int update(Class<E> klazz, CsvReader reader) 268 throws Exception { 269 throw new UnsupportedOperationException(); 155 public <E extends Entity> E findById(Class<E> klazz, Object id) { 156 return (E) em.find(klazz, id); 157 } 158 159 @Override 160 public <E extends Entity> List<E> find(Class<E> klazz, 161 QueryRule... rules) throws DatabaseException { 162 163 CriteriaBuilder cb = em.getCriteriaBuilder(); 164 CriteriaQuery<E> cq = cb.createQuery(klazz); 165 Root<E> root = cq.from(klazz); 166 cq.select(root); 167 168 JpaMapper<E> mapper = mappers.get(klazz.getName()); 169 Predicate whereClause = 170 JPAQueryGeneratorUtil.createWhere(klazz, mapper, em, root, cq, cb, rules); 171 if (whereClause != null) { 172 cq.where(whereClause); 173 } 174 175 if (!inTransaction) { 176 em.getTransaction().begin(); 177 } 178 List<E> entities = em.createQuery(cq).getResultList(); 179 if (!inTransaction) { 180 em.getTransaction().commit(); 181 } 182 183 return entities; 184 } 185 186 @Override 187 public <E extends Entity> void find(Class<E> klazz, CsvWriter writer, 188 QueryRule... rules) throws DatabaseException { 189 try { 190 JpaMapper<E> mapper = this.getMapperFor(klazz); 191 List<E> rs = executeSelect(klazz, rules); 192 // transform result set in writer 193 E entity = mapper.create(); 194 writer.writeHeader(entity); 195 int i = 0; 196 List<E> entityBatch = new ArrayList<E>(); 197 Iterator<E> iter = rs.iterator(); 198 while (iter.hasNext()) { 199 entity = iter.next(); 200 201 // JDBCTuple row = new JDBCTuple(rs); 202 // entity = mapper.create(); 203 // entity.set(row); 204 entityBatch.add(entity); 205 i++; 206 207 // write batch 208 if (i % BATCH_SIZE == 0) { 209 // load mrefs 210 // mapper.mapMrefs(this, entityBatch); 211 for (E e : entityBatch) { 212 writer.writeRow(entity); 213 } 214 entityBatch.clear(); 215 } 216 } 217 // write remaining 218 // load mrefs 219 // mapper.mapMrefs(this, entityBatch); 220 for (E e : entityBatch) { 221 writer.writeRow(e); 222 } 223 entityBatch.clear(); 224 225 logger.debug("find(" + klazz + ", CsvWriter, " 226 + Arrays.asList(rules) + "): wrote " + i + " lines."); 227 } catch (Exception e) { 228 throw new DatabaseException(e); 229 } 230 } 231 232 @Override 233 public <E extends Entity> Query<E> query(Class<E> klazz) { 234 return new QueryImp<E>(this, klazz); 235 } 236 237 @Override 238 public <E extends Entity> int add(E entity) throws DatabaseException, 239 IOException { 240 List<E> entityList = new ArrayList<E>(); 241 entityList.add(entity); 242 return this.add(entityList); 243 } 244 245 @Override 246 public <E extends Entity> int add(List<E> entities) 247 throws DatabaseException, IOException { 248 int count = 0; 249 if (entities.size() > 0) { 250 if (!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 251 em.getTransaction().begin(); 252 } 253 count = getMapperFor(entities).add(entities, em); 254 if (!inTransaction) { 255 em.getTransaction().commit(); 256 } 257 } 258 return count; 259 } 260 261 @Override 262 public <E extends Entity> int add(Class<E> klazz, CsvReader reader, 263 CsvWriter writer) throws Exception { 264 return executeUpdate(Action.ADD, klazz, reader, writer); 265 } 266 267 @Override 268 public <E extends Entity> int update(E entity) throws DatabaseException, 269 IOException { 270 List<E> entityList = new ArrayList<E>(); 271 entityList.add(entity); 272 return this.update(entityList); 273 } 274 275 @Override 276 public <E extends Entity> int update(List<E> entities) 277 throws DatabaseException, IOException { 278 int count = 0; 279 if (entities.size() > 0) { 280 if (!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 281 em.getTransaction().begin(); 282 } 283 count = getMapperFor(entities).update(entities, em); 284 if (!inTransaction) { 285 em.getTransaction().commit(); 286 } 287 } 288 return count; 289 } 290 291 @Override 292 public <E extends Entity> int update(Class<E> klazz, CsvReader reader) 293 throws Exception { 294 throw new UnsupportedOperationException(); 270 295 // return executeUpdate(Action.UPDATE, klazz, reader, null); 271 } 272 273 @Override 274 public <E extends Entity> int remove(E entity) throws DatabaseException, 275 IOException { 276 List<E> entityList = new ArrayList<E>(); 277 entityList.add(entity); 278 return this.remove(entityList); 279 } 280 281 @Override 282 public <E extends Entity> int remove(List<E> entities) 283 throws DatabaseException, IOException { 284 int count = 0; 285 try 286 { 287 if (entities.size() > 0) 288 { 289 if(!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 290 em.getTransaction().begin(); 291 } 292 count = getMapperFor(entities).remove(entities,em); 293 if(!inTransaction) { 294 em.getTransaction().commit(); 295 } 296 } 297 } catch (RollbackException ex) { 298 throw new DatabaseException(ex.getCause().getMessage()); 299 } 300 return count; 301 } 302 303 @Override 304 public <E extends Entity> int remove(Class<E> klazz, CsvReader reader) 305 throws Exception { 306 return executeUpdate(Action.REMOVE, klazz, reader, null); 307 } 308 309 @Override 310 public File getFilesource() { 311 return this.fileSource; 312 } 313 314 /** 315 * Find the mapper from this.mappers 316 * 317 * @param klazz 318 * the entity class to get the mapper from 319 * @return a mapper or a exception 320 * @throws DatabaseException 321 */ 322 public <E extends Entity> JpaMapper<E> getMapperFor(Class<E> klazz) 323 throws DatabaseException { 324 // transform to generic exception 325 JpaMapper<E> mapper = mappers.get(klazz.getName()); 326 if (mapper == null) 327 throw new DatabaseException( 328 "getMapperFor failed because no mapper available for " 329 + klazz.getName()); 330 return mapper; 331 } 332 333 /** 334 * Assign a mapper for a certain class. 335 * 336 * <pre> 337 * putMapper(Example.class, new ExampleMapper()); 338 * </pre> 339 * 340 * @param klazz 341 * the class of this Entity 342 * @param mapper 343 */ 344 protected static <E extends Entity> void putMapper(Class<E> klazz, 345 JpaMapper<E> mapper) { 346 mappers.put(klazz.getName(), mapper); 347 logger.debug("added mapper for klazz " + klazz.getName()); 348 } 349 350 @Override 351 public List<String> getEntityNames() { 352 List<String> entities = new ArrayList<String>(); 353 entities.addAll(mappers.keySet()); 354 return entities; 355 } 356 357 @Override 358 public <E extends Entity> List<E> toList(Class<E> klazz, CsvReader reader, 359 int limit) throws Exception { 360 final JpaMapper<E> mapper = this.getMapperFor(klazz); 361 final List<E> entities = new ArrayList<E>(10); 362 reader.parse(limit, new CsvReaderListener() { 363 @Override 364 public void handleLine(int line_number, Tuple line) 365 throws Exception { 366 E e = mapper.create(); 367 e.set(line, false); // parse the tuple 368 entities.add(e); 369 } 370 }); 371 return entities; 372 } 373 374 /** 375 * Local helper to find mappers for lists. 376 * 377 * @param entities 378 * list of entities to find this mapper for. 379 * @return a mapper or a exception 380 * @throws DatabaseException 381 */ 382 private <E extends Entity> JpaMapper<E> getMapperFor(List<E> entities) 383 throws DatabaseException { 384 try { 385 Class klazz = entities.get(0).getClass(); 386 return getMapperFor(klazz); 387 } catch (NullPointerException e) { 388 // transform to generic exception 389 logger.error("trying to store empty list"); 390 throw new DatabaseException( 391 "getMapperFor failed because of empty list"); 392 } 393 } 394 395 private <E extends Entity> int executeUpdate(Action action, 396 JpaMapper<E> mapper, List<E> entities) throws DatabaseException { 397 return this.executeUpdate(action, mapper, entities, true); 398 } 399 400 private <E extends Entity> int executeUpdate(Action action, 401 JpaMapper<E> mapper, List<E> entities, boolean skipFiles) 402 throws DatabaseException { 403 int updatedRows = 0; 404 try { 405 // prepare file attachments 406 mapper.prepareFileAttachements(entities, fileSource); 407 408 // insert/update/delete 409 for (int i = 0; i < entities.size(); i += BATCH_SIZE) { 410 // logger.debug("steekproef: "+entities.get(i)); 411 int endindex = Math.min(i + BATCH_SIZE, entities.size()); 412 List<E> sublist = entities.subList(i, endindex); 413 414 // get the right statement 415 switch (action) { 416 case ADD: 417 updatedRows += mapper.add(sublist, em); 418 break; 419 case UPDATE: 420 updatedRows += mapper.update(sublist, em); 421 break; 422 case REMOVE: 423 updatedRows += mapper.remove(sublist, em); 424 break; 425 } 426 427 // rename file attachments with right name and update database 428 if (!action.equals(Action.REMOVE)) { 429 if (mapper.saveFileAttachements(entities, this.fileSource)) { 430 mapper.update(sublist, em); 431 } 432 } 433 } 434 435 logger.info(updatedRows + " " 436 + mapper.create().getClass().getSimpleName() + " objects " 437 + action.toString().toLowerCase() + "ed"); 438 return updatedRows; 439 } catch (Exception sqle) { 440 throw new DatabaseException(sqle); 441 } 442 } 443 444 /** 445 * Helper function of various find functions. 446 * 447 * @param <E> 448 * @param klazz 449 * @param rules 450 * @return 451 * @throws DatabaseException 452 */ 453 private <E extends Entity> List<E> executeSelect(Class<E> klazz, 454 QueryRule... rules) throws DatabaseException { 455 JpaMapper<E> mapper = this.getMapperFor(klazz); 456 457 Integer[] limitOffset = new Integer[2]; 458 String qlWhereClause = JPAQueryGeneratorUtil.createWhereSql(mapper, 459 false, true, limitOffset, rules); 460 Integer limit = limitOffset[0]; 461 Integer offset = limitOffset[1]; 462 List<E> result = mapper.find(qlWhereClause, limit, offset, em); 463 return result; 464 } 465 466 /** 467 * 468 * @param <E> 469 * @param action 470 * @param klazz 471 * @param reader 472 * @param writer 473 * @return 474 * @throws DatabaseException 475 */ 476 private <E extends Entity> int executeUpdate(Action action, Class<E> klazz, 477 CsvReader reader, CsvWriter writer) throws DatabaseException { 478 int rowsAffected = 0; 479 try { 480 List<E> entities = toList(klazz, reader, BATCH_SIZE); 481 482 if (writer != null) 483 writer.writeHeader(entities.get(0)); 484 485 JpaMapper<E> mapper = getMapperFor(klazz); 486 while (entities.size() > 0) { 487 // add to the database 488 rowsAffected += this.executeUpdate(action, mapper, entities); 489 if (writer != null) { 490 for (E entity : entities) { 491 writer.writeRow(entity); 492 } 493 } 494 entities = toList(klazz, reader, BATCH_SIZE); 495 } 496 } catch (Exception e) { 497 throw new DatabaseException(e); 498 } 499 return rowsAffected; 500 } 501 502 @Override 503 public List<Class> getEntityClasses() { 504 505 List<Class> classes = new ArrayList<Class>(); 506 try { 507 for (String klazz : this.getEntityNames()) { 508 classes.add(Class.forName(klazz)); 509 } 510 } catch (Exception e) { 511 e.printStackTrace(); 512 } 513 return classes; 514 } 515 516 @Override 517 public void beginTx() throws DatabaseException { 518 em.getTransaction().begin(); 519 inTransaction = true; 520 } 521 522 @Override 523 public void close() throws DatabaseException { 524 throw new UnsupportedOperationException(); 525 526 } 527 528 @Override 529 public void commitTx() throws DatabaseException { 530 em.getTransaction().commit(); 531 inTransaction = false; 532 533 } 534 535 @Override 536 public Class<Entity> getClassForName(String name) { 537 throw new UnsupportedOperationException(); 538 } 539 540 541 @Override 542 public Security getSecurity() { 543 return login; 544 } 545 546 @Override 547 public boolean inTx() { 548 return inTransaction; 549 } 550 551 @Override 552 public CustomQuery query(List<String> fields) throws DatabaseException { 553 return (CustomQuery)new JpaCustomQuery(this, fields); 554 } 555 556 @Override 557 public void rollbackTx() throws DatabaseException { 558 em.getTransaction().rollback(); 559 } 560 561 @Override 562 public void setLogin(Security login) { 563 this.login = login; 564 } 565 296 } 297 298 @Override 299 public <E extends Entity> int remove(E entity) throws DatabaseException, 300 IOException { 301 List<E> entityList = new ArrayList<E>(); 302 entityList.add(entity); 303 return this.remove(entityList); 304 } 305 306 @Override 307 public <E extends Entity> int remove(List<E> entities) 308 throws DatabaseException, IOException { 309 int count = 0; 310 try { 311 if (entities.size() > 0) { 312 if (!inTransaction) { //vraag me af of dit echt nodig is? En zo ja in add, edit update? 313 em.getTransaction().begin(); 314 } 315 count = getMapperFor(entities).remove(entities, em); 316 if (!inTransaction) { 317 em.getTransaction().commit(); 318 } 319 } 320 } catch (RollbackException ex) { 321 throw new DatabaseException(ex.getCause().getMessage()); 322 } 323 return count; 324 } 325 326 @Override 327 public <E extends Entity> int remove(Class<E> klazz, CsvReader reader) 328 throws Exception { 329 return executeUpdate(Action.REMOVE, klazz, reader, null); 330 } 331 332 @Override 333 public File getFilesource() { 334 return this.fileSource; 335 } 336 337 /** 338 * Find the mapper from this.mappers 339 * 340 * @param klazz 341 * the entity class to get the mapper from 342 * @return a mapper or a exception 343 * @throws DatabaseException 344 */ 345 public <E extends Entity> JpaMapper<E> getMapperFor(Class<E> klazz) 346 throws DatabaseException { 347 // transform to generic exception 348 JpaMapper<E> mapper = mappers.get(klazz.getName()); 349 if (mapper == null) { 350 throw new DatabaseException( 351 "getMapperFor failed because no mapper available for " 352 + klazz.getName()); 353 } 354 return mapper; 355 } 356 357 /** 358 * Assign a mapper for a certain class. 359 * 360 * <pre> 361 * putMapper(Example.class, new ExampleMapper()); 362 * </pre> 363 * 364 * @param klazz 365 * the class of this Entity 366 * @param mapper 367 */ 368 protected static <E extends Entity> void putMapper(Class<E> klazz, 369 JpaMapper<E> mapper) { 370 mappers.put(klazz.getName(), mapper); 371 logger.debug("added mapper for klazz " + klazz.getName()); 372 } 373 374 @Override 375 public List<String> getEntityNames() { 376 List<String> entities = new ArrayList<String>(); 377 entities.addAll(mappers.keySet()); 378 return entities; 379 } 380 381 @Override 382 public <E extends Entity> List<E> toList(Class<E> klazz, CsvReader reader, 383 int limit) throws Exception { 384 final JpaMapper<E> mapper = this.getMapperFor(klazz); 385 final List<E> entities = new ArrayList<E>(10); 386 reader.parse(limit, new CsvReaderListener() { 387 388 @Override 389 public void handleLine(int line_number, Tuple line) 390 throws Exception { 391 E e = mapper.create(); 392 e.set(line, false); // parse the tuple 393 entities.add(e); 394 } 395 }); 396 return entities; 397 } 398 399 /** 400 * Local helper to find mappers for lists. 401 * 402 * @param entities 403 * list of entities to find this mapper for. 404 * @return a mapper or a exception 405 * @throws DatabaseException 406 */ 407 private <E extends Entity> JpaMapper<E> getMapperFor(List<E> entities) 408 throws DatabaseException { 409 try { 410 Class klazz = entities.get(0).getClass(); 411 return getMapperFor(klazz); 412 } catch (NullPointerException e) { 413 // transform to generic exception 414 logger.error("trying to store empty list"); 415 throw new DatabaseException( 416 "getMapperFor failed because of empty list"); 417 } 418 } 419 420 private <E extends Entity> int executeUpdate(Action action, 421 JpaMapper<E> mapper, List<E> entities) throws DatabaseException { 422 return this.executeUpdate(action, mapper, entities, true); 423 } 424 425 private <E extends Entity> int executeUpdate(Action action, 426 JpaMapper<E> mapper, List<E> entities, boolean skipFiles) 427 throws DatabaseException { 428 int updatedRows = 0; 429 try { 430 // prepare file attachments 431 mapper.prepareFileAttachements(entities, fileSource); 432 433 // insert/update/delete 434 for (int i = 0; i < entities.size(); i += BATCH_SIZE) { 435 // logger.debug("steekproef: "+entities.get(i)); 436 int endindex = Math.min(i + BATCH_SIZE, entities.size()); 437 List<E> sublist = entities.subList(i, endindex); 438 439 // get the right statement 440 switch (action) { 441 case ADD: 442 updatedRows += mapper.add(sublist, em); 443 break; 444 case UPDATE: 445 updatedRows += mapper.update(sublist, em); 446 break; 447 case REMOVE: 448 updatedRows += mapper.remove(sublist, em); 449 break; 450 } 451 452 // rename file attachments with right name and update database 453 if (!action.equals(Action.REMOVE)) { 454 if (mapper.saveFileAttachements(entities, this.fileSource)) { 455 mapper.update(sublist, em); 456 } 457 } 458 } 459 460 logger.info(updatedRows + " " 461 + mapper.create().getClass().getSimpleName() + " objects " 462 + action.toString().toLowerCase() + "ed"); 463 return updatedRows; 464 } catch (Exception sqle) { 465 throw new DatabaseException(sqle); 466 } 467 } 468 469 /** 470 * Helper function of various find functions. 471 * 472 * @param <E> 473 * @param klazz 474 * @param rules 475 * @return 476 * @throws DatabaseException 477 */ 478 private <E extends Entity> List<E> executeSelect(Class<E> klazz, 479 QueryRule... rules) throws DatabaseException { 480 JpaMapper<E> mapper = this.getMapperFor(klazz); 481 482 Integer[] limitOffset = new Integer[2]; 483 String qlWhereClause = JPAQueryGeneratorUtil.createWhereSql(mapper, 484 false, true, limitOffset, rules); 485 Integer limit = limitOffset[0]; 486 Integer offset = limitOffset[1]; 487 488 489 490 491 List<E> result = mapper.find(qlWhereClause, limit, offset, em); 492 return result; 493 } 494 495 /** 496 * 497 * @param <E> 498 * @param action 499 * @param klazz 500 * @param reader 501 * @param writer 502 * @return 503 * @throws DatabaseException 504 */ 505 private <E extends Entity> int executeUpdate(Action action, Class<E> klazz, 506 CsvReader reader, CsvWriter writer) throws DatabaseException { 507 int rowsAffected = 0; 508 try { 509 List<E> entities = toList(klazz, reader, BATCH_SIZE); 510 511 if (writer != null) { 512 writer.writeHeader(entities.get(0)); 513 } 514 515 JpaMapper<E> mapper = getMapperFor(klazz); 516 while (entities.size() > 0) { 517 // add to the database 518 rowsAffected += this.executeUpdate(action, mapper, entities); 519 if (writer != null) { 520 for (E entity : entities) { 521 writer.writeRow(entity); 522 } 523 } 524 entities = toList(klazz, reader, BATCH_SIZE); 525 } 526 } catch (Exception e) { 527 throw new DatabaseException(e); 528 } 529 return rowsAffected; 530 } 531 532 @Override 533 public List<Class> getEntityClasses() { 534 535 List<Class> classes = new ArrayList<Class>(); 536 try { 537 for (String klazz : this.getEntityNames()) { 538 classes.add(Class.forName(klazz)); 539 } 540 } catch (Exception e) { 541 e.printStackTrace(); 542 } 543 return classes; 544 } 545 546 @Override 547 public void beginTx() throws DatabaseException { 548 em.getTransaction().begin(); 549 inTransaction = true; 550 } 551 552 @Override 553 public void close() throws DatabaseException { 554 throw new UnsupportedOperationException(); 555 556 } 557 558 @Override 559 public void commitTx() throws DatabaseException { 560 em.getTransaction().commit(); 561 inTransaction = false; 562 563 } 564 565 @Override 566 public Class<Entity> getClassForName(String name) { 567 throw new UnsupportedOperationException(); 568 } 569 570 @Override 571 public Security getSecurity() { 572 return login; 573 } 574 575 @Override 576 public boolean inTx() { 577 return inTransaction; 578 } 579 580 @Override 581 public CustomQuery query(List<String> fields) throws DatabaseException { 582 return (CustomQuery) new JpaCustomQuery(this, fields); 583 } 584 585 @Override 586 public void rollbackTx() throws DatabaseException { 587 em.getTransaction().rollback(); 588 } 589 590 @Override 591 public void setLogin(Security login) { 592 this.login = login; 593 } 566 594 // public void finalize() throws Throwable 567 595 // { -
maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/framework/data/jpa/JpaMapper.java
r2582 r2614 8 8 9 9 import org.molgenis.framework.data.DatabaseException; 10 import org.molgenis.framework.data.QueryRule; 10 11 import org.molgenis.framework.data.jdbc.ColumnInfo.Type; 11 12 import org.molgenis.util.Entity; 12 13 13 14 /** 14 * Interface for (Database) Access Object ((DB)AO), hernoemen? (IDBOA)15 * DBAO is de J2EE naamgeving! Maar DAO is ook gebruikerlijk!16 *17 15 * @author Morris Swertz 18 16 * @author Joris Lops … … 23 21 public List<E> find(String jpaQlWhereClause, Integer limit, Integer offset, EntityManager em); 24 22 public int count(String jpaQlWhereClause, EntityManager em); 23 // public int count(EntityManager em, QueryRule... rules); 25 24 26 25 /** -
maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/framework/data/paging/AbstractPager.java
r2582 r2614 259 259 protected void reloadPage(Database db, QueryRule... rules) throws DatabaseException 260 260 { 261 setPage(db.find(klazz, rules));261 setPage(db.find(klazz, rules)); 262 262 } 263 263 -
maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/generators/data/types/DataTypeGen.java.ftl
r2582 r2614 125 125 //${field.name}[type=${field.type}] 126 126 <#if field.type == "xref"> 127 private ${JavaName(field.getXRefEntity())} _${name(field)} = null;127 private ${JavaName(field.getXRefEntity())} _${name(field)}; 128 128 //xref_field 129 129 private ${type(field)} _${name(field)}_${name(field.XRefField)} = ${default(field)}; 130 130 <#if field.XRefField != field.XRefLabelString>//xref_label 131 private String _${name(field)}_${name(field.XRefLabelString)} = null;131 private String _${name(field)}_${name(field.XRefLabelString)}; 132 132 </#if><#elseif field.type == "mref"> 133 133 private java.util.List<${JavaName(field.getXRefEntity())}> _${name(field)} = new ArrayList<${JavaName(field.getXRefEntity())}>(); … … 139 139 private ${type(field)} _${name(field)} = ${default(field)}; 140 140 <#if field.type == "enum"> 141 private String _${name(field)}_label = null;141 private String _${name(field)}_label; 142 142 private java.util.List<ValueLabel> _${name(field)}_options = new ArrayList<ValueLabel>(); 143 143 </#if> 144 144 <#if field.type == "file" || field.type=="image" > 145 private File _${name(field)}_file = null;145 private File _${name(field)}_file; 146 146 </#if> 147 147 </#if> -
maven_sequence_lims/molgenis3_4_maven/src/main/java/org/molgenis/generators/data/types/JpaDataTypeGen.java.ftl
r2582 r2614 201 201 </#if> 202 202 </#if> 203 <#if field.type == "date">203 <#if field.type == "date"> 204 204 @Temporal(TemporalType.DATE) 205 </#if> 205 </#if> 206 <#if field.type == "datetime"> 207 @Temporal(TemporalType.TIMESTAMP) 208 </#if> 209 206 210 <#if field.type == "xref"> 207 211 @ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
Note: See TracChangeset
for help on using the changeset viewer.