View Javadoc
1   /*
2    * #%L
3    * SUMARiS
4    * %%
5    * Copyright (C) 2019 SUMARiS Consortium
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as
9    * published by the Free Software Foundation, either version 3 of the
10   * License, or (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/gpl-3.0.html>.
20   * #L%
21   */
22  
23  package net.sumaris.core.dao.technical.hibernate;
24  
25  import net.sumaris.core.config.SumarisConfiguration;
26  import net.sumaris.core.exception.SumarisTechnicalException;
27  import org.hibernate.boot.MetadataSources;
28  import org.hibernate.boot.internal.MetadataBuilderImpl;
29  import org.hibernate.boot.model.IdGeneratorStrategyInterpreter;
30  import org.hibernate.boot.model.IdentifierGeneratorDefinition;
31  import org.hibernate.boot.spi.MetadataBuilderFactory;
32  import org.hibernate.boot.spi.MetadataBuilderImplementor;
33  import org.hibernate.cfg.BinderHelper;
34  import org.hibernate.id.PersistentIdentifierGenerator;
35  import org.hibernate.id.enhanced.SequenceStyleGenerator;
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  import javax.persistence.GenerationType;
40  import javax.persistence.SequenceGenerator;
41  import javax.persistence.TableGenerator;
42  
43  /**
44   * Custom implementation of MetadataBuilderFactory that handles a configurable IdGeneratorStrategyInterpreter
45   * set sumaris.persistence.sequence.increment option to set the allocation size for all sequences
46   *
47   * @author peck7 on 18/11/2019.
48   */
49  public class CustomMetadataBuilderFactory implements MetadataBuilderFactory {
50  
51      private static final Logger LOG = LoggerFactory.getLogger(CustomMetadataBuilderFactory.class);
52  
53      // default no arg constructor needed for Java Service
54      public CustomMetadataBuilderFactory() {
55      }
56  
57      @Override
58      public MetadataBuilderImplementor getMetadataBuilder(MetadataSources metadatasources, MetadataBuilderImplementor defaultBuilder) {
59  
60          SumarisConfiguration config = SumarisConfiguration.getInstance();
61  
62          // Read sumaris.persistence.sequence.increment option
63          int allocationSize = config != null ? config.getSequenceIncrementValue() : 0;
64          if (allocationSize <= 0) {
65              LOG.debug(String.format("invalid allocationSize : %s, fallback to default MetadataBuilderImplementor", allocationSize));
66              return null;
67          }
68  
69          MetadataBuilderImplementor implementor = new MetadataBuilderImpl(metadatasources, defaultBuilder.getBootstrapContext().getServiceRegistry());
70          implementor.applyIdGenerationTypeInterpreter(new ConfigurableSequenceGenerator(allocationSize));
71          return implementor;
72      }
73  
74      static class ConfigurableSequenceGenerator implements IdGeneratorStrategyInterpreter {
75  
76          private final int allocationSize;
77  
78          ConfigurableSequenceGenerator(int allocationSize) {
79              this.allocationSize = allocationSize;
80          }
81  
82          @Override
83          public String determineGeneratorName(GenerationType generationType, GeneratorNameDeterminationContext context) {
84              if (generationType == GenerationType.SEQUENCE) {
85                  return SequenceStyleGenerator.class.getName();
86              }
87              throw new SumarisTechnicalException("Only SEQUENCE strategy is allowed !");
88          }
89  
90          @Override
91          public void interpretTableGenerator(TableGenerator tableGeneratorAnnotation, IdentifierGeneratorDefinition.Builder definitionBuilder) {
92              throw new SumarisTechnicalException("Only SEQUENCE strategy is allowed !");
93          }
94  
95          @Override
96          public void interpretSequenceGenerator(
97              SequenceGenerator sequenceGeneratorAnnotation,
98              IdentifierGeneratorDefinition.Builder definitionBuilder) {
99              definitionBuilder.setName( sequenceGeneratorAnnotation.name() );
100             definitionBuilder.setStrategy( SequenceStyleGenerator.class.getName() );
101 
102             if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.catalog() ) ) {
103                 definitionBuilder.addParam(
104                     PersistentIdentifierGenerator.CATALOG,
105                     sequenceGeneratorAnnotation.catalog()
106                 );
107             }
108             if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.schema() ) ) {
109                 definitionBuilder.addParam(
110                     PersistentIdentifierGenerator.SCHEMA,
111                     sequenceGeneratorAnnotation.schema()
112                 );
113             }
114             if ( !BinderHelper.isEmptyAnnotationValue( sequenceGeneratorAnnotation.sequenceName() ) ) {
115                 definitionBuilder.addParam(
116                     SequenceStyleGenerator.SEQUENCE_PARAM,
117                     sequenceGeneratorAnnotation.sequenceName()
118                 );
119             }
120 
121             definitionBuilder.addParam(
122                 SequenceStyleGenerator.INCREMENT_PARAM,
123                 // Set allocationSize from configuration instead of annotation
124                 String.valueOf( allocationSize /*sequenceGeneratorAnnotation.allocationSize()*/ )
125             );
126             definitionBuilder.addParam(
127                 SequenceStyleGenerator.INITIAL_PARAM,
128                 String.valueOf( sequenceGeneratorAnnotation.initialValue() )
129             );
130         }
131     }
132 }