Adding missing database constraints for clients in JPA map storage.
This should ensure consistency for the store even in the event of concurrent creation of clients by multiple callers. Closes #9610
This commit is contained in:
parent
b53c5d5eee
commit
e2ac7b38f4
3 changed files with 16 additions and 6 deletions
|
@ -36,6 +36,7 @@ import javax.persistence.FetchType;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.persistence.Version;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.hibernate.annotations.TypeDef;
|
||||
|
@ -48,11 +49,16 @@ import org.keycloak.models.map.storage.jpa.hibernate.jsonb.JsonbType;
|
|||
|
||||
/**
|
||||
* There are some fields marked by {@code @Column(insertable = false, updatable = false)}.
|
||||
* Those fields are automatically generated by database from json field,
|
||||
* Those fields are automatically generated by database from json field,
|
||||
* therefore marked as non-insertable and non-updatable to instruct hibernate.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "client")
|
||||
@Table(name = "client",
|
||||
uniqueConstraints = {
|
||||
@UniqueConstraint(
|
||||
columnNames = {"realmId", "clientId"}
|
||||
)
|
||||
})
|
||||
@TypeDefs({@TypeDef(name = "jsonb", typeClass = JsonbType.class)})
|
||||
public class JpaClientEntity extends AbstractClientEntity implements Serializable {
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ limitations under the License.
|
|||
<createIndex tableName="client" indexName="client_entityVersion">
|
||||
<column name="entityversion"/>
|
||||
</createIndex>
|
||||
<createIndex tableName="client" indexName="client_realmId_clientId">
|
||||
<createIndex tableName="client" indexName="client_realmId_clientId" unique="true">
|
||||
<column name="realmid"/>
|
||||
<column name="clientid"/>
|
||||
</createIndex>
|
||||
|
|
|
@ -139,15 +139,19 @@ public class MapClientProvider implements ClientProvider {
|
|||
public ClientModel addClient(RealmModel realm, String id, String clientId) {
|
||||
LOG.tracef("addClient(%s, %s, %s)%s", realm, id, clientId, getShortStackTrace());
|
||||
|
||||
if (id != null && tx.read(id) != null) {
|
||||
throw new ModelDuplicateException("Client with same id exists: " + id);
|
||||
}
|
||||
if (clientId != null && getClientByClientId(realm, clientId) != null) {
|
||||
throw new ModelDuplicateException("Client with same clientId in realm " + realm.getName() + " exists: " + clientId);
|
||||
}
|
||||
|
||||
MapClientEntity entity = new MapClientEntityImpl();
|
||||
entity.setId(id);
|
||||
entity.setRealmId(realm.getId());
|
||||
entity.setClientId(clientId);
|
||||
entity.setEnabled(true);
|
||||
entity.setStandardFlowEnabled(true);
|
||||
if (id != null && tx.read(id) != null) {
|
||||
throw new ModelDuplicateException("Client exists: " + id);
|
||||
}
|
||||
entity = tx.create(entity);
|
||||
if (clientId == null) {
|
||||
clientId = entity.getId();
|
||||
|
|
Loading…
Reference in a new issue