1 /*
2  * Copyright 2008-2020 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      https://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.springframework.data.jpa.repository.support;
17
18 import javax.persistence.EntityManager;
19 import javax.persistence.PersistenceContext;
20
21 import org.springframework.beans.factory.ObjectProvider;
22 import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.data.jpa.repository.query.EscapeCharacter;
24 import org.springframework.data.jpa.repository.query.JpaQueryMethodFactory;
25 import org.springframework.data.mapping.context.MappingContext;
26 import org.springframework.data.querydsl.EntityPathResolver;
27 import org.springframework.data.querydsl.SimpleEntityPathResolver;
28 import org.springframework.data.repository.Repository;
29 import org.springframework.data.repository.core.support.RepositoryFactorySupport;
30 import org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport;
31 import org.springframework.lang.Nullable;
32 import org.springframework.util.Assert;
33
34 /**
35  * Special adapter for Springs {@link org.springframework.beans.factory.FactoryBean} interface to allow easy setup of
36  * repository factories via Spring configuration.
37  *
38  * @author Oliver Gierke
39  * @author Eberhard Wolff
40  * @author Mark Paluch
41  * @author Jens Schauder
42  * @author RĂ©da Housni Alaoui
43  * @param <T> the type of the repository
44  */

45 public class JpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID>
46         extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> {
47
48     private @Nullable EntityManager entityManager;
49     private EntityPathResolver entityPathResolver;
50     private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;
51     private JpaQueryMethodFactory queryMethodFactory;
52
53     /**
54      * Creates a new {@link JpaRepositoryFactoryBean} for the given repository interface.
55      *
56      * @param repositoryInterface must not be {@literal null}.
57      */

58     public JpaRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
59         super(repositoryInterface);
60     }
61
62     /**
63      * The {@link EntityManager} to be used.
64      *
65      * @param entityManager the entityManager to set
66      */

67     @PersistenceContext
68     public void setEntityManager(EntityManager entityManager) {
69         this.entityManager = entityManager;
70     }
71
72     /*
73      * (non-Javadoc)
74      * @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#setMappingContext(org.springframework.data.mapping.context.MappingContext)
75      */

76     @Override
77     public void setMappingContext(MappingContext<?, ?> mappingContext) {
78         super.setMappingContext(mappingContext);
79     }
80
81     /**
82      * Configures the {@link EntityPathResolver} to be used. Will expect a canonical bean to be present but fallback to
83      * {@link SimpleEntityPathResolver#INSTANCE} in case none is available.
84      *
85      * @param resolver must not be {@literal null}.
86      */

87     @Autowired
88     public void setEntityPathResolver(ObjectProvider<EntityPathResolver> resolver) {
89         this.entityPathResolver = resolver.getIfAvailable(() -> SimpleEntityPathResolver.INSTANCE);
90     }
91
92     /**
93      * Configures the {@link JpaQueryMethodFactory} to be used. Will expect a canonical bean to be present but will
94      * fallback to {@link org.springframework.data.jpa.repository.query.DefaultJpaQueryMethodFactory} in case none is
95      * available.
96      *
97      * @param factory may be {@literal null}.
98      */

99     @Autowired
100     public void setQueryMethodFactory(@Nullable JpaQueryMethodFactory factory) {
101
102         if (factory != null) {
103             this.queryMethodFactory = factory;
104         }
105     }
106
107     /*
108      * (non-Javadoc)
109      * @see org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport#doCreateRepositoryFactory()
110      */

111     @Override
112     protected RepositoryFactorySupport doCreateRepositoryFactory() {
113
114         Assert.state(entityManager != null"EntityManager must not be null!");
115
116         return createRepositoryFactory(entityManager);
117     }
118
119     /**
120      * Returns a {@link RepositoryFactorySupport}.
121      */

122     protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
123
124         JpaRepositoryFactory jpaRepositoryFactory = new JpaRepositoryFactory(entityManager);
125         jpaRepositoryFactory.setEntityPathResolver(entityPathResolver);
126         jpaRepositoryFactory.setEscapeCharacter(escapeCharacter);
127
128         if (queryMethodFactory != null) {
129             jpaRepositoryFactory.setQueryMethodFactory(queryMethodFactory);
130         }
131
132         return jpaRepositoryFactory;
133     }
134
135     /*
136      * (non-Javadoc)
137      * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
138      */

139     @Override
140     public void afterPropertiesSet() {
141
142         Assert.state(entityManager != null"EntityManager must not be null!");
143
144         super.afterPropertiesSet();
145     }
146
147     public void setEscapeCharacter(char escapeCharacter) {
148
149         this.escapeCharacter = EscapeCharacter.of(escapeCharacter);
150     }
151 }
152