Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions backend/src/main/java/com/moshimo/backend/domain/model/Asset.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,10 @@

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Objects;

/**
* Asset Entity - Represents a tradeable asset (stock, ETF, index, or crypto).
*
* Learning Notes:
* - @Entity: Marks this class as a JPA entity (maps to 'asset' table)
* - @Table: Explicitly specifies table name and indexes
* - @Data: Lombok generates getters, setters, toString, equals, hashCode
* - @Builder: Lombok provides builder pattern for clean object construction
* - @NoArgsConstructor/@AllArgsConstructor: Required by JPA (no-arg) and Builder pattern
* - LocalDate: Java 8+ date type, maps to SQL DATE
* - @CreationTimestamp/@UpdateTimestamp: Hibernate automatically sets timestamps
*/
@Entity
@Table(name = "asset", indexes = {
Expand All @@ -27,7 +19,9 @@
@Index(name = "idx_asset_is_active", columnList = "is_active"),
@Index(name = "idx_asset_asset_type", columnList = "asset_type")
})
@Data
@Getter
@Setter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
Expand Down Expand Up @@ -119,4 +113,16 @@ public class Asset {
@UpdateTimestamp
@Column(name = "updated_at", nullable = false)
private LocalDateTime updatedAt;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Asset other)) return false;
return Objects.equals(symbol, other.symbol);
}

@Override
public int hashCode() {
return Objects.hash(symbol);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,19 @@ Optional<AssetPrice> findNextAvailableDate(
@Param("date") LocalDate date
);

/**
* Find all dates that already have price data for a given asset within a range.
* Used by the scheduler to skip duplicates without per-record queries.
*/
@Query("SELECT ap.date FROM AssetPrice ap " +
"WHERE ap.asset.id = :assetId " +
"AND ap.date BETWEEN :startDate AND :endDate")
List<LocalDate> findDatesByAssetIdAndDateBetween(
@Param("assetId") Long assetId,
@Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate
);

/**
* Batch-fetch prices for multiple assets within a date range.
* CRITICAL OPTIMIZATION: Replaces N individual queries with single batch query.
Expand Down
Loading