Ensure that values of attributes are unique in the database
While this is already ensured on the Java level when using a Set, database inconsistencies as occurred with Hibernate could lead to follow-up problems that are hard to analyze (as seen in #11666). Closes #11671
This commit is contained in:
parent
b65d76edab
commit
cd20f45b8a
10 changed files with 34 additions and 5 deletions
|
@ -18,10 +18,14 @@ package org.keycloak.models.map.storage.jpa.client.entity;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.UniqueConstraint;
|
||||||
|
|
||||||
import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "kc_client_attribute")
|
@Table(name = "kc_client_attribute", uniqueConstraints = {
|
||||||
|
@UniqueConstraint(columnNames = {"fk_root", "name", "value"})
|
||||||
|
})
|
||||||
public class JpaClientAttributeEntity extends JpaAttributeEntity<JpaClientEntity> {
|
public class JpaClientAttributeEntity extends JpaAttributeEntity<JpaClientEntity> {
|
||||||
|
|
||||||
public JpaClientAttributeEntity() {
|
public JpaClientAttributeEntity() {
|
||||||
|
|
|
@ -18,10 +18,14 @@ package org.keycloak.models.map.storage.jpa.clientscope.entity;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.UniqueConstraint;
|
||||||
|
|
||||||
import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "kc_client_scope_attribute")
|
@Table(name = "kc_client_scope_attribute", uniqueConstraints = {
|
||||||
|
@UniqueConstraint(columnNames = {"fk_root", "name", "value"})
|
||||||
|
})
|
||||||
public class JpaClientScopeAttributeEntity extends JpaAttributeEntity<JpaClientScopeEntity> {
|
public class JpaClientScopeAttributeEntity extends JpaAttributeEntity<JpaClientScopeEntity> {
|
||||||
|
|
||||||
public JpaClientScopeAttributeEntity() {
|
public JpaClientScopeAttributeEntity() {
|
||||||
|
|
|
@ -18,10 +18,14 @@ package org.keycloak.models.map.storage.jpa.group.entity;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.UniqueConstraint;
|
||||||
|
|
||||||
import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "kc_group_attribute")
|
@Table(name = "kc_group_attribute", uniqueConstraints = {
|
||||||
|
@UniqueConstraint(columnNames = {"fk_root", "name", "value"})
|
||||||
|
})
|
||||||
public class JpaGroupAttributeEntity extends JpaAttributeEntity<JpaGroupEntity> {
|
public class JpaGroupAttributeEntity extends JpaAttributeEntity<JpaGroupEntity> {
|
||||||
|
|
||||||
public JpaGroupAttributeEntity() {
|
public JpaGroupAttributeEntity() {
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.keycloak.models.map.storage.jpa.realm.entity;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.UniqueConstraint;
|
||||||
|
|
||||||
import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
||||||
|
|
||||||
|
@ -28,7 +29,9 @@ import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
||||||
* @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
|
* @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "kc_realm_attribute")
|
@Table(name = "kc_realm_attribute", uniqueConstraints = {
|
||||||
|
@UniqueConstraint(columnNames = {"fk_root", "name", "value"})
|
||||||
|
})
|
||||||
public class JpaRealmAttributeEntity extends JpaAttributeEntity<JpaRealmEntity> {
|
public class JpaRealmAttributeEntity extends JpaAttributeEntity<JpaRealmEntity> {
|
||||||
|
|
||||||
public JpaRealmAttributeEntity() {
|
public JpaRealmAttributeEntity() {
|
||||||
|
|
|
@ -18,10 +18,14 @@ package org.keycloak.models.map.storage.jpa.role.entity;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.UniqueConstraint;
|
||||||
|
|
||||||
import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
import org.keycloak.models.map.storage.jpa.JpaAttributeEntity;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "kc_role_attribute")
|
@Table(name = "kc_role_attribute", uniqueConstraints = {
|
||||||
|
@UniqueConstraint(columnNames = {"fk_root", "name", "value"})
|
||||||
|
})
|
||||||
public class JpaRoleAttributeEntity extends JpaAttributeEntity<JpaRoleEntity> {
|
public class JpaRoleAttributeEntity extends JpaAttributeEntity<JpaRoleEntity> {
|
||||||
|
|
||||||
public JpaRoleAttributeEntity() {
|
public JpaRoleAttributeEntity() {
|
||||||
|
|
|
@ -57,6 +57,8 @@ limitations under the License.
|
||||||
<column name="name" type="VARCHAR(255)"/>
|
<column name="name" type="VARCHAR(255)"/>
|
||||||
<column name="value" type="text"/>
|
<column name="value" type="text"/>
|
||||||
</createTable>
|
</createTable>
|
||||||
|
<!-- this is deferrable and initiallyDeferred as hibernate will first insert new entries and then delete the old by default -->
|
||||||
|
<addUniqueConstraint tableName="kc_client_scope_attribute" columnNames="fk_root, name, value" deferrable="true" initiallyDeferred="true" />
|
||||||
<createIndex tableName="kc_client_scope_attribute" indexName="client_scope_attr_fk_root">
|
<createIndex tableName="kc_client_scope_attribute" indexName="client_scope_attr_fk_root">
|
||||||
<column name="fk_root"/>
|
<column name="fk_root"/>
|
||||||
</createIndex>
|
</createIndex>
|
||||||
|
|
|
@ -64,6 +64,8 @@ limitations under the License.
|
||||||
<column name="name" type="VARCHAR(255)"/>
|
<column name="name" type="VARCHAR(255)"/>
|
||||||
<column name="value" type="text"/>
|
<column name="value" type="text"/>
|
||||||
</createTable>
|
</createTable>
|
||||||
|
<!-- this is deferrable and initiallyDeferred as hibernate will first insert new entries and then delete the old by default -->
|
||||||
|
<addUniqueConstraint tableName="kc_client_attribute" columnNames="fk_root, name, value" deferrable="true" initiallyDeferred="true" />
|
||||||
<createIndex tableName="kc_client_attribute" indexName="client_attr_fk_root">
|
<createIndex tableName="kc_client_attribute" indexName="client_attr_fk_root">
|
||||||
<column name="fk_root"/>
|
<column name="fk_root"/>
|
||||||
</createIndex>
|
</createIndex>
|
||||||
|
|
|
@ -59,6 +59,8 @@ limitations under the License.
|
||||||
<column name="name" type="VARCHAR(255)"/>
|
<column name="name" type="VARCHAR(255)"/>
|
||||||
<column name="value" type="text"/>
|
<column name="value" type="text"/>
|
||||||
</createTable>
|
</createTable>
|
||||||
|
<!-- this is deferrable and initiallyDeferred as hibernate will first insert new entries and then delete the old by default -->
|
||||||
|
<addUniqueConstraint tableName="kc_group_attribute" columnNames="fk_root, name, value" deferrable="true" initiallyDeferred="true" />
|
||||||
<createIndex tableName="kc_group_attribute" indexName="group_attr_fk_root">
|
<createIndex tableName="kc_group_attribute" indexName="group_attr_fk_root">
|
||||||
<column name="fk_root"/>
|
<column name="fk_root"/>
|
||||||
</createIndex>
|
</createIndex>
|
||||||
|
|
|
@ -83,6 +83,8 @@ limitations under the License.
|
||||||
<column name="name" type="VARCHAR(255)"/>
|
<column name="name" type="VARCHAR(255)"/>
|
||||||
<column name="value" type="TEXT"/>
|
<column name="value" type="TEXT"/>
|
||||||
</createTable>
|
</createTable>
|
||||||
|
<!-- this is deferrable and initiallyDeferred as hibernate will first insert new entries and then delete the old by default -->
|
||||||
|
<addUniqueConstraint tableName="kc_realm_attribute" columnNames="fk_root, name, value" deferrable="true" initiallyDeferred="true" />
|
||||||
<createIndex tableName="kc_realm_attribute" indexName="realm_attr_fk_root">
|
<createIndex tableName="kc_realm_attribute" indexName="realm_attr_fk_root">
|
||||||
<column name="fk_root"/>
|
<column name="fk_root"/>
|
||||||
</createIndex>
|
</createIndex>
|
||||||
|
|
|
@ -66,6 +66,8 @@ limitations under the License.
|
||||||
<column name="name" type="VARCHAR(255)"/>
|
<column name="name" type="VARCHAR(255)"/>
|
||||||
<column name="value" type="text"/>
|
<column name="value" type="text"/>
|
||||||
</createTable>
|
</createTable>
|
||||||
|
<!-- this is deferrable and initiallyDeferred as hibernate will first insert new entries and then delete the old by default -->
|
||||||
|
<addUniqueConstraint tableName="kc_role_attribute" columnNames="fk_root, name, value" deferrable="true" initiallyDeferred="true" />
|
||||||
<createIndex tableName="kc_role_attribute" indexName="role_attr_fk_root">
|
<createIndex tableName="kc_role_attribute" indexName="role_attr_fk_root">
|
||||||
<column name="fk_root"/>
|
<column name="fk_root"/>
|
||||||
</createIndex>
|
</createIndex>
|
||||||
|
|
Loading…
Reference in a new issue