前言:本週主要對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
中卻不行,之前並沒有關注過這些,導致了這個錯誤。