//  [java]
    public void translate(GeyserSession session, ServerSpawnEntityPacket packet) {

        Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
        Vector3f motion = Vector3f.from(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ());
        Vector3f rotation = Vector3f.from(packet.getYaw(), packet.getPitch(), 0);

        org.geysermc.connector.entity.type.EntityType type = EntityUtils.toBedrockEntity(packet.getType());
        if (type == null) {
            session.getConnector().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.entity.type_null", packet.getType()));
            return;
        }

        Class<? extends Entity> entityClass = type.getEntityClass();
        try {
            Entity entity;
            if (packet.getType() == EntityType.FALLING_BLOCK) {
                entity = new FallingBlockEntity(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
                        type, position, motion, rotation, ((FallingBlockData) packet.getData()).getId());
            } else if (packet.getType() == EntityType.ITEM_FRAME || packet.getType() == EntityType.GLOW_ITEM_FRAME) {
                // Item frames need the hanging direction
                entity = new ItemFrameEntity(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
                        type, position, motion, rotation, (HangingDirection) packet.getData());
            } else if (packet.getType() == EntityType.FISHING_BOBBER) {
                // Fishing bobbers need the owner for the line
                int ownerEntityId = ((ProjectileData) packet.getData()).getOwnerId();
                Entity owner = session.getEntityCache().getEntityByJavaId(ownerEntityId);
                if (owner == null && session.getPlayerEntity().getEntityId() == ownerEntityId) {
                    owner = session.getPlayerEntity();
                }
                // Java clients only spawn fishing hooks with a player as its owner
                if (owner instanceof PlayerEntity) {
                    entity = new FishingHookEntity(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
                            type, position, motion, rotation, (PlayerEntity) owner);
                } else {
                    return;
                }
            } else if (packet.getType() == EntityType.BOAT) {
                // Initial rotation is incorrect
                entity = new BoatEntity(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
                        type, position, motion, Vector3f.from(packet.getYaw(), 0, packet.getYaw()));
            } else {
                Constructor<? extends Entity> entityConstructor = entityClass.getConstructor(long.class, long.class, org.geysermc.connector.entity.type.EntityType.class,
                        Vector3f.class, Vector3f.class, Vector3f.class);

                entity = entityConstructor.newInstance(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
                        type, position, motion, rotation
                );
            }
            session.getEntityCache().spawnEntity(entity);
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException ex) {
            ex.printStackTrace();
        }
    }