前言:本周主要对gitlabWebhook转github的项目写了写前台部分扫了扫尾,并没有遇到什么问题,所以就上周LDAP中的疑问进行了进一步的了解。
承接上文中的问题:@Id和@DnAttribute之间是什么关系。为什么在ldapAdmin中没有找到@ID对应的字段。
@Data
@Entry(base = "", objectClasses="inetOrgPerson")
public class Person {
/**
* 此字段不能少
*/
@Id
private Name id;
@DnAttribute(value = "uid", index = 3)
private String uid;
@DnAttribute(value = "title", index = 4)
private String title;
@Attribute(name = "cn")
private String commonName;
@Attribute(name = "sn")
private String myUerName;
private String userPassword;
}
就拿上面这个实体来说,我们可以用如下方法查询它内部的属性:
List<Person> list = ldapTemplate.search("", filter, new AttributesMapper() {
@SneakyThrows
@Override
public Object mapFromAttributes(Attributes attributes) throws NamingException {
NamingEnumeration<? extends Attribute> att = attributes.getAll();
while (att.hasMore()) {
Attribute a = att.next();
System.out.println(a.getID() + "=" + a.get());
}
}
但是结构中并没有打印出id这一项,但是如果没有这一项在创造实体时会报如下错误。
报的很直接,就是缺少ID,那么我们就要去ldapTemplate.creat函数里面去打点,看看报错是怎么来的。
测试后发现报错出现在这里:
那么我们再把ID属性添加完再来看这里。
由于我们生成ID时没有给ID赋值,他会自动生成ID,而他自动生成的ID就是由我们在试题中声明的 @DnAttribute 注解来的,根据所给的优先级进行排序生成。
就类似于@ID是由@DnAttribute统一构成的联合主键,只不过由于LDAP是树形存储,主键之间需要有优先顺序之分,来区别那一项是哪一项的上级节点。
那么他的存储形式是什么呢?
拿下面的实体来举例:
@Test
public void addPerson() {
Person person = new Person();
person.setUid("uid:17");
person.setTitle("13131000001");
person.setMyUerName("liMing");
person.setCommonName("liming");
person.setUserPassword("123456");
ldapTemplate.create(person);
}
他在库中的存储形式如下,因为UID的优先级要比title高,所以在父实体中。
那么我们如果不给@DnAttribute属性赋初值呢?
就会报如下错误:
总结来说的话就是@Id是为了构造该实体的DN而存在的,而id是根据@DnAttribute的属性生成的,LDAP中Dn的构造是源于我们一开始对基础dn的配置以及存储实体的@Id字段。
也就是说这一部分是根据@ID字段生成的
那么理所当然@DnAttribute注解字段也就不能随意更改了,如果按照之前的普通属性修改方法:
@Test
public void update(){
String oldPersonDn = "uid=uid:17";
Person newPerson = new Person();
newPerson.setUid("uid=uid:29");
ldapTemplate.modifyAttributes(oldPersonDn, new ModificationItem[] {
new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("uid", newPerson.getUid().trim())),
});
}
会报如下错误:
[LDAP: error code 64 - value of naming attribute 'uid' is not present in entry]
也就是说@DnAttribute注解后,LDAP并没有把它当做普通属性。
如果我们要修改DN的话(当然一般情况下不应修改dn)可以使用如下方法修改:
ldapTemplate.rename(oldPersonDn, newPersonDn);
遇到的其他小问题:
在初始化前台时出现了这样的报错:
Error creating bean with name 'entityManagerFactory' defined in class path resource [...]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service
. . . . . .
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service
去网上查阅之后基本都是说是配置文件没有配置完全。
下面是我的配置文件(application.properties):
server.port=8088
dingTalkUrlPre=https://oapi.dingtalk.com/robot/send
spring.datasource.driver-class-name= com.mysql.cj.jdbc.Driver
spring.datasource.url="jdbc:mysql://localhost:3310/setting?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai"
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect="org.hibernate.dialect.MySQL57Dialect"
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database=mysql
并没有发现有哪些项没有配置完全,之后才发现是因为spring.jpa.properties.hibernate.dialect
和另一个配置项后面的参数用引号括起来了,在application.yml中是否添加引号并不影响识别,但是在application.properties
中却不行,之前并没有关注过这些,导致了这个错误。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。