Ethlo back (#2267)
* Return Ethlo plugin * Return back statick weaving for EclipseLink in order to use lazy fetch
This commit is contained in:
@@ -33,6 +33,11 @@
|
|||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.persistence</groupId>
|
||||||
|
<artifactId>jakarta.persistence-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
@@ -43,12 +48,5 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Static class generation -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hibernate.orm</groupId>
|
|
||||||
<artifactId>hibernate-jpamodelgen</artifactId>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
|
||||||
*
|
|
||||||
* This program and the accompanying materials are made
|
|
||||||
* available under the terms of the Eclipse Public License 2.0
|
|
||||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit.repository.jpa.model;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import jakarta.persistence.EntityListeners;
|
|
||||||
import jakarta.persistence.MappedSuperclass;
|
|
||||||
import jakarta.persistence.PostPersist;
|
|
||||||
import jakarta.persistence.PostRemove;
|
|
||||||
import jakarta.persistence.PostUpdate;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
|
||||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
|
||||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Core information of all entities.
|
|
||||||
*/
|
|
||||||
@MappedSuperclass
|
|
||||||
@EntityListeners({ AuditingEntityListener.class, EntityInterceptorListener.class })
|
|
||||||
public abstract class AbstractBaseEntity implements BaseEntity, Serializable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defined equals/hashcode strategy for the repository in general is that an entity is equal if it has the same {@link #getId()} and
|
|
||||||
* {@link #getOptLockRevision()} and class.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
// Exception squid:S864 - generated code
|
|
||||||
@SuppressWarnings({ "squid:S864" })
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + (getId() == null ? 0 : getId().hashCode());
|
|
||||||
result = prime * result + getOptLockRevision();
|
|
||||||
result = prime * result + getClass().getName().hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defined equals/hashcode strategy for the repository in general is that an entity is equal if it has the same {@link #getId()} and
|
|
||||||
* {@link #getOptLockRevision()} and class.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!getClass().isInstance(obj)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final BaseEntity other = (BaseEntity) obj;
|
|
||||||
final Long id = getId();
|
|
||||||
final Long otherId = other.getId();
|
|
||||||
if (id == null) {
|
|
||||||
if (otherId != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!id.equals(otherId)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return getOptLockRevision() == other.getOptLockRevision();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getClass().getSimpleName() + " [id=" + getId() + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostPersist
|
|
||||||
public void postInsert() {
|
|
||||||
if (this instanceof EventAwareEntity eventAwareEntity) {
|
|
||||||
doNotify(eventAwareEntity::fireCreateEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostUpdate
|
|
||||||
public void postUpdate() {
|
|
||||||
if (this instanceof EventAwareEntity eventAwareEntity) {
|
|
||||||
doNotify(eventAwareEntity::fireUpdateEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostRemove
|
|
||||||
public void postDelete() {
|
|
||||||
if (this instanceof EventAwareEntity eventAwareEntity) {
|
|
||||||
doNotify(eventAwareEntity::fireDeleteEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void doNotify(final Runnable runnable) {
|
|
||||||
// fire events onl AFTER transaction commit
|
|
||||||
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isController() {
|
|
||||||
return SecurityContextHolder.getContext().getAuthentication() != null
|
|
||||||
&& SecurityContextHolder.getContext().getAuthentication()
|
|
||||||
.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails
|
|
||||||
&& tenantAwareDetails.isController();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
# hawkBit JPA EclipseLink Vendor integration
|
# hawkBit JPA EclipseLink Vendor integration
|
||||||
|
|
||||||
Implementation of [EclipseLink](http://www.eclipse.org/eclipselink/) JPA vendor.
|
Implementation of [EclipseLink](http://www.eclipse.org/eclipselink/) JPA vendor.
|
||||||
|
|
||||||
|
Since there seem to be bug in eclipselink static weaver or eclipselink-maven-plugin - don't weave properly the abstract classes when no non-abstract entity into the maven module - we use to have fake entity in the module to make it work.
|
||||||
@@ -52,4 +52,33 @@
|
|||||||
<version>${eclipselink.version}</version>
|
<version>${eclipselink.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- Static weaver for EclipseLink -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.ethlo.persistence.tools</groupId>
|
||||||
|
<artifactId>eclipselink-maven-plugin</artifactId>
|
||||||
|
<version>${eclipselink.maven.plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>process-classes</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>weave</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<basePackage>org.eclipse.hawkbit.repository.jpa.model</basePackage>
|
||||||
|
</configuration>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.persistence</groupId>
|
||||||
|
<artifactId>org.eclipse.persistence.jpa</artifactId>
|
||||||
|
<version>${eclipselink.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -14,29 +14,39 @@ import java.io.Serial;
|
|||||||
import jakarta.persistence.Access;
|
import jakarta.persistence.Access;
|
||||||
import jakarta.persistence.AccessType;
|
import jakarta.persistence.AccessType;
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.EntityListeners;
|
||||||
import jakarta.persistence.GeneratedValue;
|
import jakarta.persistence.GeneratedValue;
|
||||||
import jakarta.persistence.GenerationType;
|
import jakarta.persistence.GenerationType;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.MappedSuperclass;
|
import jakarta.persistence.MappedSuperclass;
|
||||||
|
import jakarta.persistence.PostPersist;
|
||||||
|
import jakarta.persistence.PostRemove;
|
||||||
|
import jakarta.persistence.PostUpdate;
|
||||||
import jakarta.persistence.Version;
|
import jakarta.persistence.Version;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||||
|
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||||
|
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||||
import org.springframework.data.annotation.CreatedBy;
|
import org.springframework.data.annotation.CreatedBy;
|
||||||
import org.springframework.data.annotation.CreatedDate;
|
import org.springframework.data.annotation.CreatedDate;
|
||||||
import org.springframework.data.annotation.LastModifiedBy;
|
import org.springframework.data.annotation.LastModifiedBy;
|
||||||
import org.springframework.data.annotation.LastModifiedDate;
|
import org.springframework.data.annotation.LastModifiedDate;
|
||||||
|
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base hawkBit entity class containing the common attributes for EclipseLink.
|
* Base hawkBit entity class containing the common attributes for EclipseLink.
|
||||||
*/
|
*/
|
||||||
@NoArgsConstructor(access = AccessLevel.PROTECTED) // Default constructor needed for JPA entities.
|
@NoArgsConstructor(access = AccessLevel.PROTECTED) // Default constructor needed for JPA entities.
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
|
@EntityListeners({ AuditingEntityListener.class, EntityInterceptorListener.class })
|
||||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities
|
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities
|
||||||
@SuppressWarnings("squid:S2160")
|
@SuppressWarnings("squid:S2160")
|
||||||
public abstract class AbstractJpaBaseEntity extends AbstractBaseEntity {
|
public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||||
|
|
||||||
protected static final int USERNAME_FIELD_LENGTH = 64;
|
protected static final int USERNAME_FIELD_LENGTH = 64;
|
||||||
|
|
||||||
@@ -116,4 +126,86 @@ public abstract class AbstractJpaBaseEntity extends AbstractBaseEntity {
|
|||||||
public long getLastModifiedAt() {
|
public long getLastModifiedAt() {
|
||||||
return lastModifiedAt == 0 ? createdAt : lastModifiedAt;
|
return lastModifiedAt == 0 ? createdAt : lastModifiedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defined equals/hashcode strategy for the repository in general is that an entity is equal if it has the same {@link #getId()} and
|
||||||
|
* {@link #getOptLockRevision()} and class.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
// Exception squid:S864 - generated code
|
||||||
|
@SuppressWarnings({ "squid:S864" })
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + (getId() == null ? 0 : getId().hashCode());
|
||||||
|
result = prime * result + getOptLockRevision();
|
||||||
|
result = prime * result + getClass().getName().hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defined equals/hashcode strategy for the repository in general is that an entity is equal if it has the same {@link #getId()} and
|
||||||
|
* {@link #getOptLockRevision()} and class.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getClass().isInstance(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final BaseEntity other = (BaseEntity) obj;
|
||||||
|
final Long id = getId();
|
||||||
|
final Long otherId = other.getId();
|
||||||
|
if (id == null) {
|
||||||
|
if (otherId != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!id.equals(otherId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getOptLockRevision() == other.getOptLockRevision();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getSimpleName() + " [id=" + getId() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostPersist
|
||||||
|
public void postInsert() {
|
||||||
|
if (this instanceof EventAwareEntity eventAwareEntity) {
|
||||||
|
doNotify(eventAwareEntity::fireCreateEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostUpdate
|
||||||
|
public void postUpdate() {
|
||||||
|
if (this instanceof EventAwareEntity eventAwareEntity) {
|
||||||
|
doNotify(eventAwareEntity::fireUpdateEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostRemove
|
||||||
|
public void postDelete() {
|
||||||
|
if (this instanceof EventAwareEntity eventAwareEntity) {
|
||||||
|
doNotify(eventAwareEntity::fireDeleteEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void doNotify(final Runnable runnable) {
|
||||||
|
// fire events onl AFTER transaction commit
|
||||||
|
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isController() {
|
||||||
|
return SecurityContextHolder.getContext().getAuthentication() != null
|
||||||
|
&& SecurityContextHolder.getContext().getAuthentication()
|
||||||
|
.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails
|
||||||
|
&& tenantAwareDetails.isController();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ public class EntityPropertyChangeListener extends DescriptorEventAdapter {
|
|||||||
final Object object = event.getObject();
|
final Object object = event.getObject();
|
||||||
if (((UpdateObjectQuery) event.getQuery()).getObjectChangeSet().getChangedAttributeNames().stream()
|
if (((UpdateObjectQuery) event.getQuery()).getObjectChangeSet().getChangedAttributeNames().stream()
|
||||||
.anyMatch(field -> !TARGET_UPDATE_EVENT_IGNORE_FIELDS.contains(field))) {
|
.anyMatch(field -> !TARGET_UPDATE_EVENT_IGNORE_FIELDS.contains(field))) {
|
||||||
AbstractBaseEntity.doNotify(((EventAwareEntity) object)::fireUpdateEvent);
|
AbstractJpaBaseEntity.doNotify(((EventAwareEntity) object)::fireUpdateEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.repository.jpa.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fake JPA entity to allow proper static compilation. It seems that if there is no actual (class) entity using AbstractJpaBaseEntity,
|
||||||
|
* the static compilation is not proper.
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = lombok.AccessLevel.PACKAGE)
|
||||||
|
@Table(name = "fake_for_static_compilation")
|
||||||
|
@Entity
|
||||||
|
public class FakeJpaEntityForStaticCompilation extends AbstractJpaTenantAwareBaseEntity {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@
|
|||||||
<artifactId>hawkbit-repository-jpa-api</artifactId>
|
<artifactId>hawkbit-repository-jpa-api</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate.orm</groupId>
|
<groupId>org.hibernate.orm</groupId>
|
||||||
<artifactId>hibernate-core</artifactId>
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
|||||||
@@ -14,29 +14,39 @@ import java.io.Serial;
|
|||||||
import jakarta.persistence.Access;
|
import jakarta.persistence.Access;
|
||||||
import jakarta.persistence.AccessType;
|
import jakarta.persistence.AccessType;
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.EntityListeners;
|
||||||
import jakarta.persistence.GeneratedValue;
|
import jakarta.persistence.GeneratedValue;
|
||||||
import jakarta.persistence.GenerationType;
|
import jakarta.persistence.GenerationType;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.MappedSuperclass;
|
import jakarta.persistence.MappedSuperclass;
|
||||||
|
import jakarta.persistence.PostPersist;
|
||||||
|
import jakarta.persistence.PostRemove;
|
||||||
|
import jakarta.persistence.PostUpdate;
|
||||||
import jakarta.persistence.Version;
|
import jakarta.persistence.Version;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||||
|
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||||
|
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||||
import org.springframework.data.annotation.CreatedBy;
|
import org.springframework.data.annotation.CreatedBy;
|
||||||
import org.springframework.data.annotation.CreatedDate;
|
import org.springframework.data.annotation.CreatedDate;
|
||||||
import org.springframework.data.annotation.LastModifiedBy;
|
import org.springframework.data.annotation.LastModifiedBy;
|
||||||
import org.springframework.data.annotation.LastModifiedDate;
|
import org.springframework.data.annotation.LastModifiedDate;
|
||||||
|
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base hawkBit entity class containing the common attributes for Hibernate.
|
* Base hawkBit entity class containing the common attributes for Hibernate.
|
||||||
*/
|
*/
|
||||||
@NoArgsConstructor(access = AccessLevel.PROTECTED) // Default constructor needed for JPA entities.
|
@NoArgsConstructor(access = AccessLevel.PROTECTED) // Default constructor needed for JPA entities.
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
|
@EntityListeners({ AuditingEntityListener.class, EntityInterceptorListener.class })
|
||||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities
|
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities
|
||||||
@SuppressWarnings("squid:S2160")
|
@SuppressWarnings("squid:S2160")
|
||||||
public abstract class AbstractJpaBaseEntity extends AbstractBaseEntity {
|
public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||||
|
|
||||||
protected static final int USERNAME_FIELD_LENGTH = 64;
|
protected static final int USERNAME_FIELD_LENGTH = 64;
|
||||||
|
|
||||||
@@ -116,4 +126,86 @@ public abstract class AbstractJpaBaseEntity extends AbstractBaseEntity {
|
|||||||
public long getLastModifiedAt() {
|
public long getLastModifiedAt() {
|
||||||
return lastModifiedAt == 0 ? createdAt : lastModifiedAt;
|
return lastModifiedAt == 0 ? createdAt : lastModifiedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defined equals/hashcode strategy for the repository in general is that an entity is equal if it has the same {@link #getId()} and
|
||||||
|
* {@link #getOptLockRevision()} and class.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
// Exception squid:S864 - generated code
|
||||||
|
@SuppressWarnings({ "squid:S864" })
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + (getId() == null ? 0 : getId().hashCode());
|
||||||
|
result = prime * result + getOptLockRevision();
|
||||||
|
result = prime * result + getClass().getName().hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defined equals/hashcode strategy for the repository in general is that an entity is equal if it has the same {@link #getId()} and
|
||||||
|
* {@link #getOptLockRevision()} and class.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getClass().isInstance(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final BaseEntity other = (BaseEntity) obj;
|
||||||
|
final Long id = getId();
|
||||||
|
final Long otherId = other.getId();
|
||||||
|
if (id == null) {
|
||||||
|
if (otherId != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!id.equals(otherId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return getOptLockRevision() == other.getOptLockRevision();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getSimpleName() + " [id=" + getId() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostPersist
|
||||||
|
public void postInsert() {
|
||||||
|
if (this instanceof EventAwareEntity eventAwareEntity) {
|
||||||
|
doNotify(eventAwareEntity::fireCreateEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostUpdate
|
||||||
|
public void postUpdate() {
|
||||||
|
if (this instanceof EventAwareEntity eventAwareEntity) {
|
||||||
|
doNotify(eventAwareEntity::fireUpdateEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostRemove
|
||||||
|
public void postDelete() {
|
||||||
|
if (this instanceof EventAwareEntity eventAwareEntity) {
|
||||||
|
doNotify(eventAwareEntity::fireDeleteEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void doNotify(final Runnable runnable) {
|
||||||
|
// fire events onl AFTER transaction commit
|
||||||
|
AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isController() {
|
||||||
|
return SecurityContextHolder.getContext().getAuthentication() != null
|
||||||
|
&& SecurityContextHolder.getContext().getAuthentication()
|
||||||
|
.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails
|
||||||
|
&& tenantAwareDetails.isController();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ public class EntityPropertyChangeListener implements PostUpdateEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasNonIgnoredChanges || !lastTargetQueryChanged) {
|
if (hasNonIgnoredChanges || !lastTargetQueryChanged) {
|
||||||
AbstractBaseEntity.doNotify(((EventAwareEntity) event.getEntity())::fireUpdateEvent);
|
AbstractJpaBaseEntity.doNotify(((EventAwareEntity) event.getEntity())::fireUpdateEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,35 @@
|
|||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- Static weaver for EclipseLink -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.ethlo.persistence.tools</groupId>
|
||||||
|
<artifactId>eclipselink-maven-plugin</artifactId>
|
||||||
|
<version>${eclipselink.maven.plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>process-classes</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>weave</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<basePackage>org.eclipse.hawkbit.repository.jpa.model</basePackage>
|
||||||
|
</configuration>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.persistence</groupId>
|
||||||
|
<artifactId>org.eclipse.persistence.jpa</artifactId>
|
||||||
|
<version>${eclipselink.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>hibernate</id>
|
<id>hibernate</id>
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.eclipse.hawkbit.repository.QuotaManagement;
|
|||||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusCreate;
|
import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusCreate;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.AbstractBaseEntity;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity_;
|
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
||||||
|
|||||||
10
hawkbit-simple-ui/.gitignore
vendored
10
hawkbit-simple-ui/.gitignore
vendored
@@ -1,3 +1,9 @@
|
|||||||
frontend
|
|
||||||
bundles
|
bundles
|
||||||
package-lock.json
|
frontend
|
||||||
|
node_modules
|
||||||
|
package.json
|
||||||
|
package-lock.json
|
||||||
|
tsconfig.json
|
||||||
|
types.d.ts
|
||||||
|
vite.config.ts
|
||||||
|
vite.generated.ts
|
||||||
3
pom.xml
3
pom.xml
@@ -51,8 +51,7 @@
|
|||||||
<!-- Eclipselink - START -->
|
<!-- Eclipselink - START -->
|
||||||
<!-- 4.0.4 doesn't work because of https://github.com/eclipse-ee4j/eclipselink/issues/2219 -->
|
<!-- 4.0.4 doesn't work because of https://github.com/eclipse-ee4j/eclipselink/issues/2219 -->
|
||||||
<eclipselink.version>4.0.5</eclipselink.version>
|
<eclipselink.version>4.0.5</eclipselink.version>
|
||||||
<!-- for some reason 3.0.2 doesn't work -->
|
<eclipselink.maven.plugin.version>3.0.2</eclipselink.maven.plugin.version>
|
||||||
<eclipselink.maven.plugin.version>3.0.1</eclipselink.maven.plugin.version>
|
|
||||||
<!-- Eclipselink - END -->
|
<!-- Eclipselink - END -->
|
||||||
|
|
||||||
<!-- Misc libraries versions - START -->
|
<!-- Misc libraries versions - START -->
|
||||||
|
|||||||
Reference in New Issue
Block a user