primaryKey
Entity.Key.primary()
returns false.- Returns:
- the primary key of this entity
- See Also:
Comparable<Entity>
An Entity instance maintains both current and original values for all attributes, tracks modifications, and provides type-safe access to column values and foreign key relationships.
Entity instances can be mutable or immutable. Mutable entities track value modifications and
support operations like set(Attribute, Object)
, revert()
, and save()
.
Immutable entities throw UnsupportedOperationException
for modification operations.
Immutable entities ARE thread-safe. Created via immutable()
, they can be safely
shared between threads. All referenced entities are also made immutable to ensure complete thread safety.
Recommended patterns for concurrent use:
immutable()
to create thread-safe snapshots for sharingcopy()
when passing entities between threads// Creating and working with entities
Entity customer = entities.builder(Customer.TYPE)
.with(Customer.ID, 42)
.with(Customer.NAME, "John Doe")
.with(Customer.EMAIL, "john@example.com")
.build();
// Accessing values
String name = customer.get(Customer.NAME);
Optional<String> email = customer.optional(Customer.EMAIL);
// Modifying values (if mutable)
customer.set(Customer.EMAIL, "newemail@example.com");
boolean isModified = customer.modified(Customer.EMAIL); // true
// Reverting changes
customer.revert(Customer.EMAIL); // back to "john@example.com"
// Working with foreign keys
Entity invoice = connection.selectSingle(Invoice.ID.equalTo(123));
// Access the referenced entity (automatically loaded if configured)
Entity customer = invoice.get(Invoice.CUSTOMER_FK);
// Access foreign key attributes directly
String customerName = invoice.get(Invoice.CUSTOMER_FK).get(Customer.NAME);
// Get the foreign key value
Key customerKey = invoice.key(Invoice.CUSTOMER_FK);
static interface
Entity
instances.static interface
static interface
static Entity.Builder
builder(Entity.Key key)
boolean
copy()
Entity.Copy
instance providing ways to create copies of this entity.static <T> Collection<T>
distinct(Attribute<T> attribute,
Collection<Entity> entities)
attribute
from the given entities.entity(ForeignKey foreignKey)
ForeignKey
.static Entity
entity(Entity.Key key)
entrySet()
boolean
equalValues(Entity entity)
boolean
equalValues(Entity entity,
Collection<? extends Attribute<?>> attributes)
boolean
exists()
<T> @Nullable T
attribute
.static LinkedHashMap<EntityType,List<Entity>>
groupByType(Collection<Entity> entities)
LinkedHashMap
containing the given entities mapped to their entityTypes,
respecting the iteration order of the given collectionstatic <T> LinkedHashMap<T,List<Entity>>
groupByValue(Attribute<T> attribute,
Collection<Entity> entities)
LinkedHashMap
containing the given entities mapped to the value of attribute
,
respecting the iteration order of the given collection
List<Entity> orders = connection.select(all(Order.TYPE));
// Group orders by status
LinkedHashMap<String, List<Entity>> ordersByStatus =
Entity.groupByValue(Order.STATUS, orders);
// Process orders by status
ordersByStatus.forEach((status, statusOrders) -> {
System.out.println("Status: " + status + ", Count: " + statusOrders.size());
});
// Groups can contain entities with null values
List<Entity> pendingOrders = ordersByStatus.get("PENDING");
List<Entity> nullStatusOrders = ordersByStatus.get(null);
boolean
key(ForeignKey foreignKey)
ForeignKey
,
if the reference is null this method returns null.static Collection<Entity.Key>
keys(ForeignKey foreignKey,
Collection<Entity> entities)
ForeignKey
boolean
modified()
boolean
boolean
mutable()
<T> Optional<T>
attribute
, wrapped in an Optional
.<T> @Nullable T
attribute
, or the current one if it is unmodified.static Collection<Entity.Key>
originalPrimaryKeys(Collection<Entity> entities)
static Map<Entity.Key,Entity>
primaryKeyMap(Collection<Entity> entities)
static Collection<Entity.Key>
primaryKeys(Collection<Entity> entities)
<T> @Nullable T
void
revert()
void
void
save()
void
<T> @Nullable T
<T> String
type()
static <T> Collection<T>
values(Attribute<T> attribute,
Collection<Entity> entities)
attribute
from the given entities.static <T> Collection<T>
values(Collection<Entity.Key> keys)
compareTo
T
- the value typeattribute
- the attributevalue
- the valueUnsupportedOperationException
- in case this entity is immutableattribute
.T
- the value typeattribute
- the attribute for which to retrieve the valueattribute
, wrapped in an Optional
.T
- the value typeattribute
- the attribute which value to retrieveOptional
attribute
, or the current one if it is unmodified.T
- the value typeattribute
- the attribute for which to retrieve the original valueT
- the value typeattribute
- the attribute which value to retrieveattribute
attribute
- the attribute for which to revert the valueUnsupportedOperationException
- in case this entity is immutableUnsupportedOperationException
- in case this entity is immutableattribute
- the attribute for which to save the valueUnsupportedOperationException
- in case this entity is immutableUnsupportedOperationException
- in case this entity is immutableT
- the value typeattribute
- the attribute to removeUnsupportedOperationException
- in case this entity is immutableattribute
- the attributeattribute
- the attributeForeignKey
.
If the underlying reference contains a value, that is,
a foreign key value exists but the actual referenced entity has not
been loaded, an "empty" entity is returned, containing only the referenced
key value(s). Null is returned only if the actual foreign key is null.
// Assuming Invoice has a foreign key to Customer
Entity invoice = connection.selectSingle(Invoice.ID.equalTo(42));
// Get the customer entity - may be fully loaded or just contain the key
Entity customer = invoice.entity(Invoice.CUSTOMER_FK);
if (customer != null) {
// This is always available - the foreign key value
Integer customerId = customer.get(Customer.ID);
// This may return null if customer wasn't loaded
// and the foreign key definition doesn't include Customer.NAME
String customerName = customer.get(Customer.NAME);
}
foreignKey
- the foreign key for which to retrieve the referenced entityforeignKey
ForeignKey
,
if the reference is null this method returns null.foreignKey
- the foreign key for which to retrieve the underlying Entity.Key
Entity customer = entities.builder(Customer.TYPE)
.with(Customer.NAME, "John")
.with(Customer.EMAIL, "john@example.com")
.build();
customer.modified(Customer.NAME); // false
customer.set(Customer.NAME, "Jane");
customer.modified(Customer.NAME); // true
customer.save();
customer.modified(Customer.NAME); // false
attribute
- the attributeEntity customer1 = entities.builder(Customer.TYPE)
.with(Customer.ID, 42)
.with(Customer.NAME, "John Doe")
.with(Customer.EMAIL, "john@example.com")
.build();
Entity customer2 = entities.builder(Customer.TYPE)
.with(Customer.ID, 42)
.with(Customer.NAME, "John Doe")
.with(Customer.EMAIL, "john@example.com")
.with(Customer.PHONE, "555-1234") // Extra attribute
.build();
customer1.equalValues(customer2); // true - all values in customer1 exist and are equal in customer2
customer2.equalValues(customer1); // false - customer2 has PHONE which customer1 doesn't have
entity
- the entity to compare toIllegalArgumentException
- in case the entity is not of the same typeEntity customer1 = entities.builder(Customer.TYPE)
.with(Customer.ID, 42)
.with(Customer.NAME, "John Doe")
.with(Customer.EMAIL, "john@example.com")
.build();
Entity customer2 = entities.builder(Customer.TYPE)
.with(Customer.ID, 42)
.with(Customer.NAME, "John Doe")
.with(Customer.EMAIL, "different@example.com")
.build();
// Compare only specific attributes
Set<Attribute<?>> nameAttributes = Set.of(Customer.ID, Customer.NAME);
customer1.equalValues(customer2, nameAttributes); // true - ID and NAME are equal
Set<Attribute<?>> allAttributes = Set.of(Customer.ID, Customer.NAME, Customer.EMAIL);
customer1.equalValues(customer2, allAttributes); // false - EMAIL differs
entity
- the entity to compare toattributes
- the attributes to compareIllegalArgumentException
- in case the entity is not of the same typeentity
- the entity to copy or null for clearing all values in this instanceIllegalArgumentException
- in case the entity is not of the same typeUnsupportedOperationException
- in case this entity is immutableEntity.Copy
instance providing ways to create copies of this entity.
Entity customer = entities.builder(Customer.TYPE)
.with(Customer.ID, 42)
.with(Customer.NAME, "John Doe")
.with(Customer.EMAIL, "john@example.com")
.build();
// Create a mutable copy
Entity mutableCopy = customer.copy().mutable();
mutableCopy.set(Customer.EMAIL, "new@example.com");
// Original remains unchanged
customer.get(Customer.EMAIL); // "john@example.com"
mutableCopy.get(Customer.EMAIL); // "new@example.com"
// Create a builder initialized with entity values
Entity newCustomer = customer.copy().builder()
.with(Customer.ID, 43) // Different ID
.with(Customer.PHONE, "555-1234") // Additional field
.build();
Entity.Copy
instance for this entityThread Safety: The returned immutable entity is thread-safe and can be safely shared between threads without external synchronization. All referenced entities are also made immutable to ensure complete thread safety throughout the object graph.
This method is particularly useful for:
Thread Safety: Mutable entities (returning true
) are NOT thread-safe
and should not be shared between threads without external synchronization.
Immutable entities (returning false
) are thread-safe and can be safely
shared between threads.
Entity.Key.primary()
returns false.key
- the keykey
- the keyentities
- the entitiesCollection
containing the primary keys of the given entitiesForeignKey
foreignKey
- the foreign keyentities
- the entitiesCollection
containing the non-null keys referenced by the given ForeignKey
entities
- the entitiesCollection
containing the primary keys of the given entities with their original valuesT
- the value typekeys
- the keysIllegalStateException
- in case of a composite keyattribute
from the given entities.T
- the value typeattribute
- the attribute which values to retrieveentities
- the entities from which to retrieve the attribute valueattribute
from the given entities.T
- the value typeattribute
- the attribute which values to retrieveentities
- the entities from which to retrieve the valuesList<Entity> customers = connection.select(Customer.ID.in(1, 2, 3));
// Create a map for fast lookup by primary key
Map<Key, Entity> customerMap = Entity.primaryKeyMap(customers);
// Later, quick lookup by key
Key customerKey = entities.primaryKey(Customer.TYPE, 2);
Entity customer = customerMap.get(customerKey);
entities
- the entities to mapIllegalArgumentException
- in case a non-unique primary key is encounteredLinkedHashMap
containing the given entities mapped to the value of attribute
,
respecting the iteration order of the given collection
List<Entity> orders = connection.select(all(Order.TYPE));
// Group orders by status
LinkedHashMap<String, List<Entity>> ordersByStatus =
Entity.groupByValue(Order.STATUS, orders);
// Process orders by status
ordersByStatus.forEach((status, statusOrders) -> {
System.out.println("Status: " + status + ", Count: " + statusOrders.size());
});
// Groups can contain entities with null values
List<Entity> pendingOrders = ordersByStatus.get("PENDING");
List<Entity> nullStatusOrders = ordersByStatus.get(null);
T
- the key typeattribute
- the attribute which value should be used for mappingentities
- the entities to map by attribute valueLinkedHashMap
of the given entities mapped to the attribute valueLinkedHashMap
containing the given entities mapped to their entityTypes,
respecting the iteration order of the given collectionentities
- the entities to map by entityTypeLinkedHashMap
of the given entities mapped to their EntityType