6

I was following the samples of Spring LDAP project and was trying to convert xml configuration to Java Configuration.

I am trying to do CRUD operations on the LDAP server.

I was able to figure out the following,

This is the xml configuration for the application, which I am hoping to convert into Java Config.

<context:property-placeholder location="classpath:/ldap.properties"
        system-properties-mode="OVERRIDE" />
    <context:annotation-config />

    <ldap:context-source id="contextSource" password="${sample.ldap.password}"
        url="${sample.ldap.url}" username="${sample.ldap.userDn}" base="${sample.ldap.base}" />

    <ldap:ldap-template id="ldapTemplate"
        context-source-ref="contextSource" />

    <!-- This will scan the org.springframework.ldap.samples.useradmin.domain 
        package for interfaces extending CrudRepository (in our case, LdapRepository), 
        automatically creating repository beans based on these interfaces. -->
    <ldap:repositories base-package="com.cazysystems.appstore.model" />

    <!-- This one will never be referenced directly, but the ldap:repositories 
        tag will make sure it will be 'wired in', because the GroupRepo interface 
        extends from an interface that GroupRepoImpl imlements. -->
    <bean class="com.cazysystems.appstore.model.impli.GroupRepoImpl" />

    <bean class="com.cazysystems.appstore.model.impli.DepartmentRepoImpl" />

    <bean class="com.cazysystems.appstore.service.UserService">
        <property name="directoryType" value="${sample.ldap.directory.type}" />
    </bean>

So I have the following classes that are supposed to do the migration,

@Configuration
@EnableLdapRepositories("com.cazysystems.appstore.model")
public class LdapConfiguration {

    @Autowired
    Environment env;

    @Bean
    public LdapContextSource contextSource() {
        LdapContextSource contextSource = new LdapContextSource();
        contextSource.setUrl(env.getRequiredProperty("sample.ldap.url"));
        contextSource.setBase(env.getRequiredProperty("sample.ldap.base"));
        contextSource.setUserDn(env.getRequiredProperty("sample.ldap.userDn"));
        contextSource.setPassword(env
                .getRequiredProperty("sample.ldap.password"));
        return contextSource;
    }

    @Bean
    public LdapTemplate ldapTemplate() {
        return new LdapTemplate(contextSource());
    }

}

and the

 @Configuration
public class AuthenticationConfiguration extends
        GlobalAuthenticationConfigurerAdapter {

    @Autowired
    Environment env;

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {

        auth.ldapAuthentication()
                // .userDetailsContextMapper(userDetailsContextMapper())
                .userDnPatterns(
                        env.getRequiredProperty("ldap.user_dn_patterns"))
                .groupSearchBase(
                        env.getRequiredProperty("ldap.group_search_base"))
                .contextSource().ldif("classpath:setup_data.ldif")
                .url(env.getRequiredProperty("sample.ldap.url"))
                .managerDn("sample.ldap.userDn")
                .managerPassword("sample.ldap.password").port(10389);
    }

}

But when I run the application,

I get the following error,

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.cazysystems.appstore.model.Group

But under the com.cazysystems.appstore.modelpackage,

I have,

public interface GroupRepo extends LdapRepository<Group>, GroupRepoExtension {
    public final static String USER_GROUP = "ROLE_USER";

    Group findByName(String groupName);

    @Query("(member={0})")
    Collection<Group> findByMember(Name member);
}

and

@Entry(objectClasses = { "groupOfNames", "top" }, base = "ou=Groups")
public final class Group {
    @Id
    private Name id;

    @Attribute(name = "cn")
    @DnAttribute(value = "cn", index = 1)
    private String name;

    @Attribute(name = "description")
    private String description;

    @Attribute(name = "member")
    private Set<Name> members = new HashSet<Name>();

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Set<Name> getMembers() {
        return members;
    }

    public void addMember(Name newMember) {
        members.add(newMember);
    }

    public void removeMember(Name member) {
        members.remove(member);
    }

    public Name getId() {
        return id;
    }

    public void setId(Name id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

But this annotation is supposed to do the trick, But it is not working,

@EnableLdapRepositories("com.cazysystems.appstore.model")

I am using the following dependencies in my pom.

<dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-ldap</artifactId>
    </dependency>


    <dependency>
        <groupId>org.springframework.ldap</groupId>
        <artifactId>spring-ldap-core</artifactId>
        <version>2.0.3.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.ldap</groupId>
        <artifactId>spring-ldap-core-tiger</artifactId>
        <version>2.0.3.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-commons</artifactId>
    </dependency>

I am not sure what I am doing wrong, because the documentation on this are very hard to find. Please help if you know this stuff.

EDIT:

Here is my Controller class,

@Controller
public class GroupController {

    @Autowired
    private GroupRepo groupRepo;

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/groups", method = GET)
    public String listGroups(ModelMap map) {
        map.put("groups", groupRepo.getAllGroupNames());
        return "listGroups";
    }

    @RequestMapping(value = "/newGroup", method = GET)
    public String initNewGroup() {
        return "newGroup";
    }

    @RequestMapping(value = "/groups", method = POST)
    public String newGroup(Group group) {
        groupRepo.create(group);

        return "redirect:groups/" + group.getName();
    }

    @RequestMapping(value = "/groups/{name}", method = GET)
    public String editGroup(@PathVariable String name, ModelMap map) {
        Group foundGroup = groupRepo.findByName(name);
        map.put("group", foundGroup);

        final Set<User> groupMembers = userService.findAllMembers(foundGroup.getMembers());
        map.put("members", groupMembers);

        Iterable<User> otherUsers = Iterables.filter(userService.findAll(), new Predicate<User>() {
            @Override
            public boolean apply(User user) {
                return !groupMembers.contains(user);
            }
        });
        map.put("nonMembers", Lists.newLinkedList(otherUsers));

        return "editGroup";
    }

    @RequestMapping(value = "/groups/{name}/members", method = POST)
    public String addUserToGroup(@PathVariable String name, @RequestParam String userId) {
        Group group = groupRepo.findByName(name);
        group.addMember(userService.toAbsoluteDn(LdapUtils.newLdapName(userId)));

        groupRepo.save(group);

        return "redirect:/groups/" + name;
    }

    @RequestMapping(value = "/groups/{name}/members", method = DELETE)
    public String removeUserFromGroup(@PathVariable String name, @RequestParam String userId) {
        Group group = groupRepo.findByName(name);
        group.removeMember(userService.toAbsoluteDn(LdapUtils.newLdapName(userId)));

        groupRepo.save(group);

        return "redirect:/groups/" + name;
    }
}

EDIT:

The following is the complete stack trace,

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cazysystems.appstore.domain.GroupRepo com.eazysystems.appstore.controller.GroupController.groupRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.cazysystems.appstore.domain.Group
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
    at com.eazysystems.appstore.Application.main(Application.java:20)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cazysystems.appstore.domain.GroupRepo com.eazysystems.appstore.controller.GroupController.groupRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.eazysystems.appstore.domain.Group
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 16 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.eazysystems.appstore.domain.Group
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 18 common frames omitted
Caused by: java.lang.IllegalArgumentException: Not an managed type: class com.cazysystems.appstore.domain.Group
    at org.hibernate.jpa.internal.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:219)
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:68)
    at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:67)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:145)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:89)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:69)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:173)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
    ... 28 common frames omitted

My UserService class as following,

@Component
public class UserService implements BaseLdapNameAware {

    @Autowired
    private UserRepo userRepo;

    @Autowired
    private GroupRepo groupRepo;

    private LdapName baseLdapPath;

    @Autowired
    @Value("${sample.ldap.directory.type}")
    private DirectoryType directoryType;

    /*
     * @Autowired public UserService(UserRepo userRepo, GroupRepo groupRepo) {
     * this.userRepo = userRepo; this.groupRepo = groupRepo; }
     */
    public Group getUserGroup() {
        return groupRepo.findByName(GroupRepo.USER_GROUP);
    }

    public void setDirectoryType(DirectoryType directoryType) {
        this.directoryType = directoryType;
    }

    @Override
    public void setBaseLdapPath(LdapName baseLdapPath) {
        this.baseLdapPath = baseLdapPath;
    }

    public Iterable<User> findAll() {
        return userRepo.findAll();
    }

    public User findUser(String userId) {
        return userRepo.findOne(LdapUtils.newLdapName(userId));
    }

    public User createUser(User user) {
        User savedUser = userRepo.save(user);

        Group userGroup = getUserGroup();

        // The DN the member attribute must be absolute
        userGroup.addMember(toAbsoluteDn(savedUser.getId()));
        groupRepo.save(userGroup);

        return savedUser;
    }

    public LdapName toAbsoluteDn(Name relativeName) {
        return LdapNameBuilder.newInstance(baseLdapPath).add(relativeName)
                .build();
    }

    /**
     * This method expects absolute DNs of group members. In order to find the
     * actual users the DNs need to have the base LDAP path removed.
     *
     * @param absoluteIds
     * @return
     */
    public Set<User> findAllMembers(Iterable<Name> absoluteIds) {
        return Sets.newLinkedHashSet(userRepo
                .findAll(toRelativeIds(absoluteIds)));
    }

    public Iterable<Name> toRelativeIds(Iterable<Name> absoluteIds) {
        return Iterables.transform(absoluteIds, new Function<Name, Name>() {
            @Override
            public Name apply(Name input) {
                return LdapUtils.removeFirst(input, baseLdapPath);
            }
        });
    }

    public User updateUser(String userId, User user) {
        LdapName originalId = LdapUtils.newLdapName(userId);
        User existingUser = userRepo.findOne(originalId);

        existingUser.setFirstName(user.getFirstName());
        existingUser.setLastName(user.getLastName());
        existingUser.setFullName(user.getFullName());
        existingUser.setEmail(user.getEmail());
        existingUser.setPhone(user.getPhone());
        existingUser.setTitle(user.getTitle());
        existingUser.setDepartment(user.getDepartment());
        existingUser.setUnit(user.getUnit());

        if (directoryType == DirectoryType.AD) {
            return updateUserAd(originalId, existingUser);
        } else {
            return updateUserStandard(originalId, existingUser);
        }
    }

    /**
     * Update the user and - if its id changed - update all group references to
     * the user.
     *
     * @param originalId
     *            the original id of the user.
     * @param existingUser
     *            the user, populated with new data
     *
     * @return the updated entry
     */
    private User updateUserStandard(LdapName originalId, User existingUser) {
        User savedUser = userRepo.save(existingUser);

        if (!originalId.equals(savedUser.getId())) {
            // The user has moved - we need to update group references.
            LdapName oldMemberDn = toAbsoluteDn(originalId);
            LdapName newMemberDn = toAbsoluteDn(savedUser.getId());

            Collection<Group> groups = groupRepo.findByMember(oldMemberDn);
            updateGroupReferences(groups, oldMemberDn, newMemberDn);
        }
        return savedUser;
    }

    /**
     * Special behaviour in AD forces us to get the group membership before the
     * user is updated, because AD clears group membership for removed entries,
     * which means that once the user is update we've lost track of which groups
     * the user was originally member of, preventing us to update the membership
     * references so that they point to the new DN of the user.
     *
     * This is slightly less efficient, since we need to get the group
     * membership for all updates even though the user may not have been moved.
     * Using our knowledge of which attributes are part of the distinguished
     * name we can do this more efficiently if we are implementing specifically
     * for Active Directory - this approach is just to highlight this quite
     * significant difference.
     *
     * @param originalId
     *            the original id of the user.
     * @param existingUser
     *            the user, populated with new data
     *
     * @return the updated entry
     */
    private User updateUserAd(LdapName originalId, User existingUser) {
        LdapName oldMemberDn = toAbsoluteDn(originalId);
        Collection<Group> groups = groupRepo.findByMember(oldMemberDn);

        User savedUser = userRepo.save(existingUser);
        LdapName newMemberDn = toAbsoluteDn(savedUser.getId());

        if (!originalId.equals(savedUser.getId())) {
            // The user has moved - we need to update group references.
            updateGroupReferences(groups, oldMemberDn, newMemberDn);
        }
        return savedUser;
    }

    private void updateGroupReferences(Collection<Group> groups,
            Name originalId, Name newId) {
        for (Group group : groups) {
            group.removeMember(originalId);
            group.addMember(newId);

            groupRepo.save(group);
        }
    }

    public List<User> searchByNameName(String lastName) {
        return userRepo.findByFullNameContains(lastName);
    }
}

During the trouble shooting,

I noticed that, the application fails only when I used both JPA and LDAP together. When I removed all the JPA dependencies and implementations, the application works as expected.

The issue seems to be caused by the conflict between JPA and LDAP dependencies. But I am not sure how to resolve it.

0

2 Answers 2

1

You are not stating what you want to achive, create a user, read user, seems to me you are mixing stuff from spring-data with ldap. Ill paste my configuration maybe it helps, if it does i can show you how im adding users with this configurations, again im not sure what you want to achieve, hope it helps

@Configuration
public class LdapManagerConfiguration {

@Autowired
Environment ldapProperties;

@Bean
public LdapContextSource contextSourceTarget() {
    LdapContextSource ldapContextSource = new LdapContextSource();
    ldapContextSource.setUrl(ldapProperties.getProperty("auth.ldap.url"));
    ldapContextSource.setBase(ldapProperties.getProperty("auth.ldap.base"));
    ldapContextSource.setUserDn(ldapProperties
            .getProperty("auth.ldap.userdn"));
    ldapContextSource.setPassword(ldapProperties
            .getProperty("auth.ldap.password"));

    return ldapContextSource;

}

@Bean
public LdapTemplate ldapTemplate() {

    return new LdapTemplate(contextSourceTarget());

}

@Bean
public InetOrgPersonContextMapper inetOrgPersonContextMapper() {
    return new InetOrgPersonContextMapper();
}

@Bean
public DefaultLdapUsernameToDnMapper defaultLdapUsernameToDnMapper() {
    return new DefaultLdapUsernameToDnMapper(
            ldapProperties.getProperty("auth.ldap.groupbase"),
            ldapProperties.getProperty("auth.ldap.attributename.username"));// "uid"
}

@Bean
public LdapUserDetailsManager ldapUserDetailManager() {
    LdapUserDetailsManager userManager = new LdapUserDetailsManager(
            contextSourceTarget());

    userManager.setGroupSearchBase(ldapProperties
            .getProperty("auth.ldap.groupbase"));
    userManager.setUserDetailsMapper(inetOrgPersonContextMapper());
    userManager.setUsernameMapper(defaultLdapUsernameToDnMapper());
    userManager.setGroupRoleAttributeName(ldapProperties
            .getProperty("auth.ldap.attributename.grouprole"));
    userManager.setGroupMemberAttributeName(ldapProperties
            .getProperty("auth.ldap.attributename.groupmemeber"));

    return userManager;

}

}

to add a user then

Logger logger = LoggerFactory.getLogger(LdapUserManagerImpl.class);

@Autowired
LdapTemplate ldapTemplate;

@Autowired
Environment ldapProperties;

final String passwordAttribute = "userPassword";

@Override
public boolean createUser(final String user,
        final String defaultPasswordPolicy)
        throws UserAlreadyExistsAsInactive {

    boolean created = false;

    String inactivePeople = ldapProperties.getProperty(
            "auth.ldap.inactive.groupbase").replace("ou=", "");

    String activePeople = ldapProperties.getProperty("auth.ldap.groupbase")
            .replace("ou=", "");

    if (existsUser(user, inactivePeople)) {
        logger.error("User " + user
                + " already exists in ldap but it's incative");
        throw new UserAlreadyExistsAsInactive(user);

    }
    if (existsUser(user, activePeople)) {
        logger.error("User " + user
                + " already exists in ldap and is Active");
        return false;
    }

    try {

        ldapTemplate.bind(buildDn(user, inactivePeople), null,
                createUserDetails(user, defaultPasswordPolicy));
        created = true;

    } catch (Exception e) {
        logger.error(
                "Unexpected exception when trying to create user in LdapException",
                e);
        return created;
    }
    return created;
}

So That Will Be the create

This would be de read

public UserI findUser(String userName, String group) {

    try {
        String dn = buildDN(userName, group);
        User user = ldapTemplate.lookup(dn, new UserAttributesMapper());
        return user;
    } catch (NameNotFoundException e) {
        return new UserNullObject();
    }

}

This the update

@Override
public void changeUserGroup(String userName, String oldGroup,
        String newGroup) throws ReLocoException {

    UserI user = findUser(userName, oldGroup);
    if (!user.isEmpty()) {

        try {

            Object password = getLdapPassword(userName, oldGroup);

            ldapTemplate.unbind(buildDN(userName, oldGroup));

            String defaultPasswordPolicy = ldapProperties
                    .getProperty("auth.ldap.default.userpollicy");

            ldapTemplate.bind(buildDN(userName, newGroup), null,
                    createUserDetails(userName, defaultPasswordPolicy));

            applyPasswordToUser(userName, password, newGroup);

        } catch (Exception e) {
            logger.error("Error on change user from incative to active people group "
                    + e);
            throw new ConfirmAccountValidationCodeException(userName);
        }
    } else {

        throw new UserNotFoundException(
                "The username provided for the given group '" + oldGroup
                        + "' does not exist");
    }

}
Sign up to request clarification or add additional context in comments.

2 Comments

I am not sure if I am able to use your configuration. Because I want the ldap for the authentication as well as for the CRUD on the LDAP server. I updated my answer and see if you can help me further. Appreciate your help very much.
Ok then yes, do use my configuration. there you have how to add a user, I ll edit my response and how you how to get a user
0

Do you have your application annotated with @SpringBootApplication or @EnableAutoConfiguration? If so, the automatic @Repository and @Entity scanning may be wrongly identifying your LDAP repository as a JPA repository, hence the error. Try excluding the automatic configuration for JPA Repositories from your application's automatic configuration: @SpringBootApplication(exclude={JpaRepositoriesAutoConfiguration.class})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.