Skip to content

wenchien/CodeReview-BetterReads-DataLoader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CodeReview-BetterReads-DataLoader section

Why?

I was following a pretty interesting code-along series by Java Brains on Youtube https://youtu.be/LxVGFBRpEFM. Check it out! However, I feel like some things can be modified to be more suitable This repository is dedicated to my thoughts on what can be changed and why. I will be making continuous modification as I go through the project. This is also a documentation for what I've learned.

Changes - Move logics out of main class

In the video, a lot of the parsing, retrievals are written under the main class with @PostConstruct. In my opinion, this is barely justified. Instead I moved a lot of the logics to a new class:

@Component
@Slf4j
public class LoadData {
  // All Author / Book creation logics
}

See the full LoadData class

Changes - JSONObject -> GSON

As mentioned in the previous section, after moving everything out of the main class, I modify the use of JSONObjects. Instead of JSONOjbect, I resort to GSON and added a custom PostProcessable.PostProcessingEnabler class that implements TypeAdapterFactory.

See the custom TypeAdapter here

And then have the Author and Book beans implement PostProcessable interface and hide all the data processing in each Bean's gsonPostProcess() and isPostProcessOk(). Therefore you only need to call methods like the following snippet:

Gson gson = new GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(new PostProcessable.PostProcessingEnabler()).create();
Author gsonAuthor = gson.fromJson(jsonString, Author.class);

Changes - System.out.println -> SLF4J

In my honest opinion, there's no reason to use System.out.println() directly in code. Quoting from Baeldung page https://www.baeldung.com/logback:

Unlike the messages in the sample snippets above, most useful log messages require appending Strings. This entails allocating memory, serializing objects, concatenating Strings, and potentially cleaning up the garbage later.

Consider the following message:

log.debug("Current count is " + count);
We incur the cost of building the message whether the Logger logs the message or not.

Logback offers an alternative with its parameterized messages:

log.debug("Current count is {}", count);
The braces {} will accept any Object and uses its toString() method to build a message only after verifying that the log message is required.

Changes - Relying on source action -> Lombok

I like lombok. It saves me a lot of time

Changes - Cleaner stream

I honestly like to follow the saying One stream, one purpose / operation (from my boss). So I rewrote the stream section that finds the ID from Cassandra db.

private void populateBookAuthorNames(Gson gson, Book gsonBook) {
		Optional<Author> authors = gsonBook.getAuthorIds().stream()
                                                            .map(id -> authorRepository
                                                            .findById(id))
                                                            .findFirst()
                                                            .orElse(Optional.empty());
                                                            
		authors.ifPresentOrElse(author -> gsonBook.getAuthorNames().add(author.getName()), 
                                () -> {gsonBook.getAuthorNames().add("Unknown Author");});
	}

Changes - Added new LocalDateDeserializer

GSON requires this when serializing / deserializing LocalDateTime, LocalDate. This is something new I learned.

private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");

    @Override
    public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
        
        return LocalDate.parse(json.getAsString(), formatter.withLocale(Locale.ENGLISH));
    }

Changes - Moved Book and Author to package io.jdevelop.DTO and BookRepository and AuthorRepository to io.jdevelop.repository

package standards man, package standards

Changes - Added .cql

For bookkeeping

Changes - changed CassandraColumn type from Name.LIST to Name.SET

According to DataStax Documentation, the description for LIST is of the following:

CAUTION:
Lists have limitations and specific performance considerations. Use a frozen list to decrease impact. In general, use a set instead of list.

So I changed it to SET and it's completely fine for the context of this project.

Changes - Added EncodingUtil class and change how description is processed

// Process description and set post processed result to descriptionStr
        if (null != this.getDescription()) {
            for(Map.Entry<String, String> entry : this.getDescription().entrySet()) {
                if (Strings.isNullOrEmpty(this.getDescriptionStr())) {
                    this.setDescriptionStr(EncodingUtil.encodeValue(entry.getValue()));
                } else {
                    this.setDescriptionStr(this.getDescriptionStr() + " " + EncodingUtil.encodeValue(entry.getValue()));
                }
            }
        }

Changes - Changed author id parsing

Because we're using GSON, we have to parse the authorIds a little differently than what was shown in the video. However, if you analyze the data first, then you will realize a simple pattern:

  • Author Ids will (most likely) end with the letter 'A'
  • Books (Works) will (most likely) end with the letter 'W'
	String parsedAuthorId = this.getAuthors().toString();
        String beforeSplit = parsedAuthorId.substring(parsedAuthorId.indexOf("/authors/"), parsedAuthorId.indexOf("A", parsedAuthorId.indexOf("/authors/")) + 1).replaceAll("/authors/", "");
        log.info(beforeSplit);
        if (!Strings.isNullOrEmpty(beforeSplit)) {
            this.getAuthorIds().add(beforeSplit);
        }

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages